java - 使用synchronized 会使这段代码有顺序吗?

标签 java multithreading threadpool executorservice synchronized

我是线程池新手,正在学习使用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);
    }
}

但我认为在第二个实现中,使用线程是没有意义的,因为执行将是“某种”顺序​​的。因为两个线程中只有一个线程可以访问对象监视器,而另一个线程将等待第一个线程执行,并且只有在第一个线程完成后才可以访问监视器。这听起来像是连续的。

如有错误,请指正。非常感谢任何帮助。

最佳答案

是的。非静态方法上的同步关键字将给定方法限制为每个实例顺序执行。您只有一个 Counter 实例,并且将其重用于所有任务,因此,即使您有一个包含 2 个线程的线程池,在任何给定时间只有一个线程会执行 run()。

关于java - 使用synchronized 会使这段代码有顺序吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58780394/

相关文章:

objective-c - 调度队列 : How to tell if they're running and how to stop them

C# OpenFileDialog 线程启动但未显示对话框

java - Tomcat 线程!= JVM 线程?

java - 在这种情况下如何从字符串中获取子字符串?

java - 如何从放心的 JsonPath 中获取 List<JsonPath>

C::Threads 不一致地打开发送套接字

java - 在线程池执行器中顺序处理文件

java - 为什么我在 Flying Saucer 中的柜台上突然出现 NPE?

java - 将 TestNG 测试标记为已通过

java - Camel Split EIP 和池中线程的使用似乎没有超过最小线程