我是线程池的新手,正在学习使用synchronized
此代码具有竞争条件的问题:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit ;
public class Counter implements Runnable{
int count;
public Counter(){
count=0;
}
public void run(){
count++;
}
public static void main(String[] args) throws
InterruptedException{
ExecutorService exec=Executors.newFixedThreadPool(2);
Counter task=new Counter();
for (int i=0;i<1000;i++ ) {
exec.execute(task);
}
exec.shutdown();
exec.awaitTermination(50L,TimeUnit.SECONDS);
System.out.println(task.count);
}
}
在此代码中消除竞争条件:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit ;
public class Counter implements Runnable{
int count;
public Counter(){
count=0;
}
public synchronized void run(){
count++;
}
public static void main(String[] args) throws
InterruptedException{
ExecutorService exec=Executors.newFixedThreadPool(2);
Counter task=new Counter();
for (int i=0;i<1000;i++ ) {
exec.execute(task);
}
exec.shutdown();
exec.awaitTermination(50L,TimeUnit.SECONDS);
System.out.println(task.count);
}
}
但是我认为在第二种实现中,没有必要使用线程,因为执行将是“顺序的”。因为两个线程中只有一个线程可以访问对象监视器,而另一个线程则要等到第一个线程执行后才能访问,并且只有在第一个线程完成后才可以成为对象的监视器。这听起来像是顺序的。
如果我错了,请纠正我。非常感谢您的帮助。
使run()方法同步是一种使多线程无效的方法。当然会导致顺序处理
是。非静态方法上的synced关键字将给定方法限制为按实例顺序执行。您只有一个Counter实例,并且正在为所有任务重用它,因此,即使您有一个带有2个线程的线程池,在任何给定时间也只有一个在执行run()。