使用同步是否会使此代码顺序化?

问题描述 投票:0回答:2

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

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

如果我错了,请纠正我。非常感谢您的帮助。

java multithreading threadpool executorservice synchronized
2个回答
0
投票

使run()方法同步是一种使多线程无效的方法。当然会导致顺序处理

请参阅Should you synchronize the run method? Why or why not?


0
投票

是。非静态方法上的synced关键字将给定方法限制为按实例顺序执行。您只有一个Counter实例,并且正在为所有任务重用它,因此,即使您有一个带有2个线程的线程池,在任何给定时间也只有一个在执行run()。

© www.soinside.com 2019 - 2024. All rights reserved.