synchronized 关键字和实例方法上的锁

synchronized keyword and locks on instance methods

我目前正在学习并发,我正在学习阻塞线程。

我知道,当相应的附加任务试图访问因另一个线程获得锁而被锁定的方法时,线程可能会进入阻塞状态。

因此,根据我所阅读的任务块,等待它可以访问该方法,然后继续其业务(即 运行() 方法的其余部分)。

那么为什么这段代码会退出,就像任务可以调用 syn.getI() 并在 "erroneous" 状态下访问变量一样(即使 syn.manipulate() 方法被锁定,所以我假设任务无法调用 getI() ) ?我哪里错了?

public class SynchronizedClass {
    private int i;
    private boolean flag=true;
    public SynchronizedClass(int i){
        this.i=i;
    }
    public int getI(){
        return i;
    }
    public boolean getFlag(){
        return flag;
    }
    public synchronized void manipulate(){
        i=(i*2)+1;  //odd number
        Thread.yield();
        i= i+1; //even number       
    }
    public void close(){
        flag=false;
    }

}
public class MyThread implements Runnable {
    //auto-managed runnable
    Thread t;
    SynchronizedClass syn;
    public MyThread(SynchronizedClass syn){
        this.syn=syn;
        t=new Thread(this);
        t.start();
    }
    @Override
    public void run() {
        while(syn.getFlag()==true){
            syn.manipulate();
            if (syn.getI()%2!=0){
                syn.close();
                System.out.println("exit");
            }

        }

    }
    public static void main(String[] args) {
        SynchronizedClass syn = new SynchronizedClass(1);
        for(int i=0;i<4;++i)
            new MyThread(syn);
    }
}

even if the syn.manipulate() method is locked so I'm assuming the task cannot get to calling getI()

我相信这就是你犯的错误。

仅仅因为 one 方法是同步的并不意味着其他任何东西都是同步的。它不像拥有与对象关联的监视器的线程阻止其他线程访问该对象 - 它只是阻止其他线程获取监视器。

如果使 getI() 方法同步, 一个线程由于 manipulate() 而拥有监视器意味着其他线程调用 getI()在同一个对象上必须等待,才能获取监视器。