Делает ли использование synchronized этот код последовательным? - PullRequest
0 голосов
/ 09 ноября 2019

Я новичок в пулах потоков и учусь использовать 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);
    }
}

В этом коде условие гонки принимается с заботойoff:

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);
    }
}

Но я думаю, что во второй реализации нет смысла использовать потоки, так как выполнение будет "своего рода" последовательным. Поскольку только один поток из двух будет иметь доступ к объектному монитору, в то время как другой будет ожидать выполнения первого потока и будет иметь доступ к монитору только после завершения первого. Это звучит как последовательное.

Пожалуйста, поправьте меня, если я ошибаюсь. Любая помощь высоко ценится.

Ответы [ 2 ]

1 голос
/ 09 ноября 2019

Да. Ключевое слово synchronized в нестатических методах ограничивает данный метод последовательным выполнением для каждого экземпляра. У вас есть только один экземпляр Counter, и вы повторно используете его для всех задач, поэтому, даже если у вас есть пул потоков с 2 потоками, только один из них будет выполнять run () в любой момент времени.

0 голосов
/ 09 ноября 2019

Создание метода run () синхронизировано - это своего рода аннулирование многопоточности. Это, конечно, приводит к последовательной обработке

Пожалуйста, посмотрите Следует ли синхронизировать метод запуска? Почему или почему нет?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...