java监视器是否包含实例变量?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (84)

在java中的监视器是不是限制对实例变量的访问,而只限于在synchronized语句中声明同步或代码的方法?

我创建了两个线程,thread y调用sync方法,该方法声明为synchronized,同时thread r调用未声明同步的unsync方法。都调用共享对象上的方法s

Thread r能够修改对象的实例变量,s而该对象的监视器或锁仍然由该对象保存thread y

Java中的监视器是否不限制对实例变量的访问,并且仅限于在同步语句中声明同步或代码的方法?

public class stuff {

    private int a = 10;

    public synchronized void sync() {
        long t1 = System.currentTimeMillis();
        System.out
                .println("Okay, I am in sync method. I will be waiting for 10 seconds. Current Time = "
                        + System.currentTimeMillis());
        while (System.currentTimeMillis() - t1 < 10000);
        System.out
                .println("Okay, I have waited for 10 seconds. Current time is "
                        + System.currentTimeMillis()
                        + ".Now I will exit from sync method, a= " + this.a);
    }

    public void unsync() {
        System.out
                .println("Alright, I am in unsync method the currrent time is "
                        + System.currentTimeMillis());
        this.a = this.a + 1;
        System.out.println("The time of exit from unsync method is "
                + System.currentTimeMillis());

    }
}

class t1 extends Thread {
    stuff s;

    public t1(stuff s) {
        this.s = s;
    }

    public void run() {
        s.sync();
    }
}

class t2 extends Thread {
    stuff s;

    public t2(stuff s) {
        this.s = s;
    }

    public void run() {
        s.unsync();
    }
}

class m {
    public static void main(String args[]) throws Exception {
        stuff s = new stuff();
        t1 y = new t1(s);
        t2 r = new t2(s);
        y.start();
        Thread.sleep(2000);
        r.start();
    }
}

该程序的输出如下:

Okay, I am in sync method. I will be waiting for 10 seconds. Current Time = 1358801766310
Alright, I am in unsync method the currrent time is 1358801768343
The time of exit from unsync method is 1358801768343
Okay, I have waited for 10 seconds. Current time is 1358801776310.Now I will exit from sync method,
a= 11
提问于
用户回答回答于

是。保持对象的监视器可以防止另一个线程执行另一个代码块或在同一个对象上进行同步。如果某个方法未同步,则任何线程都可以随时调用它,而不管另一个线程是否持有显示器。

如果有可能至少有一个线程修改此共享状态,则每次访问共享声明(即使是只读访问)都必须进行同步。

用户回答回答于

在java中的监视器是不是限制对实例变量的访问,而只限于在synchronized语句中声明同步或代码的方法?

同步块(或方法)除其他外是互斥的。这并不妨碍用作锁的对象(监视器,让我们称之为lock)在这些块之外使用,在这种情况下,将不会执行同步。例如,一个线程可以读或写,lock而另一个线程lock在显示器的同步块内。

如果你想限制对一个变量的访问,你需要确保所有的访问都是在锁定的情况下进行的(任何锁定,只要每次访问都是一样的)。

扫码关注云+社区

领取腾讯云代金券