Java 同步方法不作为锁工作??为什么不锁定计数
如下面代码所示,我对我的Java 同步方法不作为锁工作??为什么不锁定计数,java,multithreading,thread-safety,locking,synchronize,Java,Multithreading,Thread Safety,Locking,Synchronize,如下面代码所示,我对我的count变量使用了强化锁(监视器),通过将synchIncrement()方法设置为同步方法,一次只能访问一个线程。那么O/P应该是20000,但仍然会出现一些时差值 为什么? 公共类SynchBlockThread{ 私有整数计数=0; 私有同步的void synchIncrement(){ 计数++; } 公共静态void main(字符串[]args){ SynchBlockThread sBT=新的SynchBlockThread(); sBT.doWork()
count
变量使用了强化锁(监视器),通过将synchIncrement()
方法设置为同步方法,一次只能访问一个线程。那么O/P应该是20000
,但仍然会出现一些时差值
为什么?
公共类SynchBlockThread{
私有整数计数=0;
私有同步的void synchIncrement(){
计数++;
}
公共静态void main(字符串[]args){
SynchBlockThread sBT=新的SynchBlockThread();
sBT.doWork();
}
私房{
线程t1=新线程(新的可运行线程(){
@凌驾
公开募捐{
对于(inti=0;i来说,这是一个很难发现的问题
在doWork()
方法的末尾,您加入了线程t1
两次,因此打印结果时线程t2
仍在工作
要用代码表示它,请执行以下操作:
try {
t1.join();
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
应该是
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
同步方法的作用是正确的。问题是,您没有等待第二个线程在第二个线程终止之前打印计数,因此您还应该添加t2.join();
:
try {
t1.join();
t2.join();
} catch (InterruptedException e) { ... }
让我们考虑一下你的方法的一个更有趣的版本:
private void doWork() throws InterruptedException {
final int n = 2;
final CountDownLatch latch = new CountDownLatch(n);
final ExecutorService service = Executors.newFixedThreadPool(n);
final Runnable task = () -> {
for (int i = 0; i < 10000; i++) {
synchIncrement();
}
latch.countDown();
};
for (int i = 0; i < n; ++i) {
service.execute(task);
}
latch.await();
service.shutdown();
System.out.println(count);
}
private void doWork()引发InterruptedException{
最终整数n=2;
最终倒计时闩锁=新倒计时闩锁(n);
final ExecutorService service=Executors.newFixedThreadPool(n);
最终可运行任务=()->{
对于(int i=0;i<10000;i++){
synchIncrement();
}
倒计时();
};
对于(int i=0;i
我引入了一个固定大小的ExecutorService
来避免自己创建线程。我编写了一个CountDownLatch
来知道所有任务何时完成执行,这样我就可以关闭服务并打印结果。不需要提供整个屏幕的屏幕截图来证明您得到的值与不同de>20000
。默认情况下,我们相信您:)
private void doWork() throws InterruptedException {
final int n = 2;
final CountDownLatch latch = new CountDownLatch(n);
final ExecutorService service = Executors.newFixedThreadPool(n);
final Runnable task = () -> {
for (int i = 0; i < 10000; i++) {
synchIncrement();
}
latch.countDown();
};
for (int i = 0; i < n; ++i) {
service.execute(task);
}
latch.await();
service.shutdown();
System.out.println(count);
}