Как я понял, создается 4 нити, и каждая из них должна увеличивать на 1 каждый элемент массива values. Но этого не происходит. Почему? Какую роль выполняет мьютекс this в синхронизации в данной задаче?
public class Solution {
public static void main(String[] args) throws InterruptedException {
Counter counter1 = new Counter();
Counter counter2 = new Counter();
Counter counter3 = new Counter();
Counter counter4 = new Counter();
counter1.start();
counter2.start();
counter3.start();
counter4.start();
for (int i = 1; i <= 100; i++) {
System.out.println("значение " + i + "= " + values[i]);
// if (values[i] != 1) {
// System.out.println("Массив values содержит элементы неравные 1");
// break;
// }
}
}
public static Integer count = 0;
public static int[] values = new int[105];
static {
for (int i = 0; i < 105; i++) {
values[i] = 0;
}
}
public static void incrementCount() {
count++;
}
public static int getCount() {
return count;
}
public static class Counter extends Thread {
@Override
public void run() {
do {
synchronized (this) {
incrementCount();
values[getCount()]++;
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
} while (getCount() < 100);
}
}
}
Не успевают значения инкрементиться. Главный поток запускает 4 counter-а и сразу начинает выводить значения values, не дожидаясь завершения counter-ов. Если перед выводом написать:
counter1.join()
counter2.join()
counter3.join()
counter4.join()
, то в результате появятся числа.
Мютекс this означает, что во время выполнения инкремента счетчиков никто не сможет обратитья к данному экзепляру класса Counter. В данном коде synchronized (this) не делает ничего полезного.
Также в данном коде есть проблемы с одновременным доступом к counter и values из нескольких потоков.
В итоге рабочий код будет примерно таким:
package com.company;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String[] args) throws InterruptedException {
Counter counter1 = new Counter();
Counter counter2 = new Counter();
Counter counter3 = new Counter();
Counter counter4 = new Counter();
counter1.start();
counter2.start();
counter3.start();
counter4.start();
counter1.join();
counter2.join();
counter3.join();
counter4.join();
for (int i = 1; i <= 100; i++) {
System.out.println("значение " + i + "= " + values[i]);
}
}
public static AtomicInteger count = new AtomicInteger(0);
public static int[] values = new int[105];
static {
for (int i = 0; i < 105; i++) {
values[i] = 0;
}
}
public static void incrementCount() {
count.incrementAndGet();
}
public static int getCount() {
return count.get();
}
public static class Counter extends Thread {
@Override
public void run() {
do {
synchronized (values) {
incrementCount();
values[getCount()]++;
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
} while (getCount() < 100);
}
}
}
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости