Java监视器

时间:2017-10-02 22:36:26

标签: java multithreading synchronized monitor

我目前正在学习在Java中使用monitor,但我不知道同步方法是如何工作的。

我理解当一个线程在同步方法中时,另一个线程不能在同步方法中,并且睡眠不会取消监视器自己的所有权。

所以我试着编写一个代码来测试

import java.util.Random;
public class ex3 extends Thread {

private static int nbA=0;
private static int nbB=0;
public static final Random rand = new Random();

public void run(){
    while(true){
        System.out.println(nbA+" "+nbB);
        try{
            Thread.sleep(rand.nextInt(500));
        }catch (Exception e ){e.printStackTrace();}
        if (rand.nextBoolean()){
            try {
                A();
            } catch (InterruptedException e) {}
        }else{
            try {
                B();
            } catch (InterruptedException e) {}
        }
    }
}

public synchronized void A() throws InterruptedException{
    nbA++;
    Thread.sleep(rand.nextInt(500));
    nbA--;
}

public synchronized void B() throws InterruptedException{   
    nbB++;
    Thread.sleep(rand.nextInt(500));
    nbB--;
}

public static void main(String[] argv){
    new ex3().start();
    new ex3().start();
    new ex3().start();
}
}

我认为nbA或nbB不可能优于1,或者nbB和nbA都不是> 0但是它正在发生

我误解了什么?

抱歉英语不好。

2 个答案:

答案 0 :(得分:0)

您正在对不同的对象进行同步:synchronized非静态方法会在this上进行同步,因此每个new ex3()实例都有效地工作,就像它不是同步。

同步实例方法与此完全相同:

public void A() {
    synchronized (this) {
        // The body.
    }
}

创建同步方法static,或者在类(或其他共享对象)上显式同步:

public void A() throws InterruptedException{
    synchronized (ex3.class) {
        nbA++;
        Thread.sleep(rand.nextInt(500));
        nbA--;
    }
}

答案 1 :(得分:0)

  

我理解当一个线程在同步方法中时,另一个线程不能在同步方法中

错误。它不能位于同一个对象上的同步方法内。它可以在任何其他同步方法中,或者在不同对象上同步的相同方法,如此处。

  

并且睡眠不会取消显示器自己的所有权。

正确。

NB Per Brinch Hansen并不认为Java有监视器,他发明了它们。