Java 使用synchronized是否使此代码具有顺序性?
我是线程池新手,正在学习使用同步 该代码存在竞争条件问题:Java 使用synchronized是否使此代码具有顺序性?,java,multithreading,threadpool,executorservice,synchronized,Java,Multithreading,Threadpool,Executorservice,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;
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方法同步有助于避免多线程。它当然会导致顺序处理
请参见是。非静态方法上的synchronized关键字将给定方法限制为每个实例顺序执行。您只有一个计数器实例,并且正在将其用于所有任务,因此,即使您有一个包含两个线程的线程池,在任何给定时间都只有一个线程在运行。首先,上面提供的代码仅用于学习案例,这使学习者知道在使用多线程时可能发生的竞争条件,同时知道如何处理竞争条件。在上面提供的代码中,它确实是顺序的,因为synchronized关键字make只有一个线程可以访问块关键部分。考虑到上下文切换时间可以忽略且调度公平,多线程版本的运行时间将大于单线程版本中使用的时间 但是退一步。我们可以从多线程中得到的好处是,我们可以同时执行程序的多个部分。因此,多线程通过多任务处理实现CPU的最大利用率。所以实际上我们需要考虑两种情况。一个是CPU密集型程序,例如代码中的示例。另一种是具有大量I/O或网络绑定处理的程序,这在web应用程序中非常常见 第二个将变得有趣,因为整个过程不是在CPU中发生的 例如,我们有 任务1:2秒从I/O+2秒CPU请求一些数据 task2:2秒从I/O+2秒CPU请求一些数据 如果我们在一个线程中运行,那么总时间将是2s+2s+2s+2s=8秒。 但是如果我们在两个线程中运行,并且假设线程上下文切换将花费1秒,那么实际时间非常快,我们可以忽略 在0处启动->任务1 I/O请求 ->task1块和线程上下文更改为task2,taks2在1s开始发出I/O请求 ->task2块和线程上下文更改为task1,task1从2秒的IO获取所有数据 ->任务2在4s时完成CPU操作 ->线程上下文在5s时更改为task2 ->任务2在7秒时完成CPU ->结束
考虑到1s上下文切换时间和3个上下文切换3s=7s。这仍然比单线程程序好。是的,在这里使用线程是无用的。您可能对object及其incrementAndGet方法感兴趣。比…优越。好链接,谢谢