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

标签 java synchronized

Java 中的监视器是否不限制对实例变量的访问,而只限制声明为synchronized 的方法或synchronized 语句中的代码?

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

Thread r 能够修改对象 s 的实例变量,而 monitor 或者 lock对象仍由 thread y 持有。

Java 中的监视器是否不限制对实例变量的访问,而只限制声明为synchronized 的方法或synchronized 语句中的代码?

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 current 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 Main {

    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 current 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 - Java监视器是否包含实例变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14447095/

相关文章:

java - spring 3中的springmodules包发生了什么

java - 在对象上同步并更改引用

Java:使用锁时是否所有可变变量都需要可变?

java - 为什么要同步Java方法Provider.getService(String type,String algorithm)?

javascript - 具有同步用户提示的异步功能

java - 返回之前的搜索结果

java - 如何在 Java 中查找默认字符集/编码?

java - findWithingHorizo​​n 方法中的 Horizo​​n

java - 如果检查的字符串仍然有剩余字符,如何使正则表达式匹配失败?

java - 从同一个对象的同步方法调用同步方法