【发布时间】:2020-12-28 16:40:44
【问题描述】:
假设在这个demo中使用了2个线程。假设increment()代码块首先执行并获取当前对象上的监视器。是否其他线程将无法执行方法decrement()? .
谁能帮我理解?
如果我运行应用程序,其他线程能够执行非同步方法,即使对象被休眠 10000 ms 的线程锁定。
package com.learn.threads;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadDemo {
int sharedVariable;
public ThreadDemo(int sharedVariable) {
this.sharedVariable = sharedVariable;
}
public synchronized void increment() throws InterruptedException {
Thread.sleep(10000);
this.sharedVariable++;
}
public void decrement() throws InterruptedException {
this.sharedVariable--;
}
public static void main(String[] args) throws InterruptedException {
ThreadDemo task = new ThreadDemo(0);
ExecutorService incrementExecutorService = Executors.newFixedThreadPool(2);
for (int i = 0; i < 6; i++) {
incrementExecutorService.submit(() -> {
try {
task.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread.sleep(5000);
incrementExecutorService.submit(() -> {
try {
task.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
Thread.sleep(35000);
incrementExecutorService.shutdown();
System.out.println(task.sharedVariable);
}
}
【问题讨论】:
-
由于递减不同步,它不会尝试获取任何锁,而是继续执行它的操作。但它的更改可能对其他线程不可见。增量和减量运算符也不是线程安全的。所以这段代码有几个问题。
-
谢谢。只有执行同步方法/块的线程才会检查对象上的锁。
-
代码包含竞争条件,因为递减与递增或并发递减并不互斥。所以你可以松动更新。它还包含数据竞争,因为变量的读/写(由于非同步递减方法)不是由发生在关系之前排序的。
标签: java multithreading synchronized