类上的锁不应该阻止所有类实例的线程

发布于 2024-11-16 02:44:21 字数 817 浏览 2 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

私野 2024-11-23 02:44:21

x 不是一个static 变量。将其更改为静态

静态字符串 x = "varun";


编辑
或者将相同对象作为参数传递给t1t2

Fern f = new Fern();
Thread t1 = new Thread(f); // pass the same object
Thread t2 = new Thread(f);

x is not a static variable. Change it to static.

static String x = "varun";


EDIT:
or pass the same object as parameter to t1 and t2.

Fern f = new Fern();
Thread t1 = new Thread(f); // pass the same object
Thread t2 = new Thread(f);
你是年少的欢喜 2024-11-23 02:44:21

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 of x in the first thread doesn't affect the x 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 implemented Runnable rather than extending Thread - you're currently passing one thread to another one's constructor, which doesn't make much sense...

一城柳絮吹成雪 2024-11-23 02:44:21

线程的每个实例中的 x 都是不同的。在这两种情况下尝试使用 private static String x 来使用共享的 x

The x in each instance of the thread is a different one. Try private static String x to use a shared x in both cases.

两相知 2024-11-23 02:44:21

这与同步无关。 x 是一个实例变量,因此每个 Fern 实例都有自己的副本,初始化为“varun”,然后打印,然后设置为“Anku”。

This has nothing to do with synchronization. x is an instance variable, so each Fern instance has its own copy, initialized to "varun", then printed, then set to "Anku".

西瑶 2024-11-23 02:44:21

由于您有两个不同的 Fern 实例,其中一个实例更改其 x 字段的值这一事实不会被另一个实例看到。 (我猜测,因为您没有给出 x 的声明。为了获得更好的答案,请仅发布完整代码。)

Because you have two different Fern instances, the fact that one of them changes the value of its x field is not seen by the other. (I am guessing, since you don't give the declaration of x. To get better answers, post only complete code.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文