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

标签 java multithreading synchronized

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

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

因此,从我读到的内容来看,任务 block 并等待直到它可以访问该方法,然后继续其业务(即 run() 方法的其余部分)。

那么为什么这段代码会退出,就像任务可以调用 syn.getI() 并以“错误”状态访问变量(即使 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()

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

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

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

关于java - synchronized 关键字和实例方法上的锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29344865/

相关文章:

c++ - std::vector 与一位读者和一位作者的多线程同步:仅在调整大小时锁定

java - 使用 waitFor() 的程序无法像在 Windows 上那样在 Linux 上运行

java - 同步块(synchronized block)和 while 循环优化排序

java - 命令行太长。缩短测试或 JUnit 默认配置的命令行?

java - 在 Linux 中运行时如何在 Java 中创建符号链接(symbolic link)?

java - Ignite 线程池使用 - 如何正确地将数据并行放入缓存中?

multithreading - Rust:允许多个线程修改图像(向量的包装)?

java - 同步获取 ConcurrentHashMap 引用?

java - Apache Commonfs VFS 避免增加临时目录

java - Hibernate 期待 "all",发现 '(' - 这是什么意思?