类上的锁不应该阻止所有类实例的线程
public class Fern extends Thread
{
private String x = "varun";
public void run()
{
synchronized(Fern.class){
System.out.println(x);
try {
sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
x = "Anku";
}
}
public static void main(String args[]) throws Exception
{
Fern f = new Fern();
Thread t1 = new Thread(new Fern());
Thread t2 = new Thread(new Fern());
t1.start();
t2.start();
}
}
输出是: 瓦伦 varun
由于该块已在 Fern.class 上同步,因此每次只允许一个线程进入该块,无论它属于哪个实例,因为所有实例的类只有一个锁。如果我将 Thread 构造函数中的 new Fern() 替换为单个 Fern 对象,则输出为: 瓦伦 安库。 如果我同步(this),该行为就会发生。 我不明白为什么会发生这种情况,因为我同步了
public class Fern extends Thread
{
private String x = "varun";
public void run()
{
synchronized(Fern.class){
System.out.println(x);
try {
sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
x = "Anku";
}
}
public static void main(String args[]) throws Exception
{
Fern f = new Fern();
Thread t1 = new Thread(new Fern());
Thread t2 = new Thread(new Fern());
t1.start();
t2.start();
}
}
Output is:
varun
varun
Since the block has been synchronized on Fern.class, only one thread should be allowed to enter the block at a time irrespective of which instance it belongs to since there is only one lock for the class for all instances. If I replace new Fern() in the Thread constructor with a single Fern object, the output is:
varun
Anku.
The behaviour is what would have been had I synchronized on(this).
I dont understand why this is happening since I synchronized
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
x
不是一个static
变量。将其更改为静态
。编辑:
或者将相同对象作为参数传递给
t1
和t2
。x
is not astatic
variable. Change it tostatic
.EDIT:
or pass the same object as parameter to
t1
andt2
.x
是一个实例变量 - 换句话说,即使一次只有一个线程可以进入该块,它们也会查看不同的变量。更改第一个线程中的x
值不会影响第二个线程正在查看的x
。换句话说,同步是“正确的”(如果您不希望多个线程进入该块,无论如何),但您的数据访问没有按照您认为应该的方式进行。
附带说明一下,我个人更喜欢锁定只有我的班级才能看到的引用。
作为另一个旁注,如果
Fern
实现Runnable
而不是扩展Thread
会更好 - 你目前将一个线程传递给另一个线程的构造函数,这没有多大意义......x
is an instance variable - in other words, even though only one thread can enter that block at a time, they're looking at different variables. Changing the value ofx
in the first thread doesn't affect thex
that the second thread is looking at.In other words, the synchronization is "correct" (if you don't want more than one thread to enter that block regardless of instance) but your data access isn't doing what you think it should.
As a side note, I personally prefer locking on references which only my class can see.
As another side note, it would be better if
Fern
implementedRunnable
rather than extendingThread
- you're currently passing one thread to another one's constructor, which doesn't make much sense...线程的每个实例中的 x 都是不同的。在这两种情况下尝试使用
private static String x
来使用共享的x
。The
x
in each instance of the thread is a different one. Tryprivate static String x
to use a sharedx
in both cases.这与同步无关。
x
是一个实例变量,因此每个Fern
实例都有自己的副本,初始化为“varun”,然后打印,然后设置为“Anku”。This has nothing to do with synchronization.
x
is an instance variable, so eachFern
instance has its own copy, initialized to "varun", then printed, then set to "Anku".由于您有两个不同的
Fern
实例,其中一个实例更改其x
字段的值这一事实不会被另一个实例看到。 (我猜测,因为您没有给出x
的声明。为了获得更好的答案,请仅发布完整代码。)Because you have two different
Fern
instances, the fact that one of them changes the value of itsx
field is not seen by the other. (I am guessing, since you don't give the declaration ofx
. To get better answers, post only complete code.)