Почему не инкрементируются значения?

328
27 сентября 2017, 09:00

Как я понял, создается 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);
        }
    }
}
Answer 1

Не успевают значения инкрементиться. Главный поток запускает 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);
        }
    }
}
READ ALSO
Выводит на экран по 2 раза System.out.println(&#39;&#39;&#39;)

Выводит на экран по 2 раза System.out.println(''')

Такая ситуация - внутри метода вызываю Systemout

251
Как получить число прописью на разных языках (рус., англ., укр. и прочие)? [требует правки]

Как получить число прописью на разных языках (рус., англ., укр. и прочие)? [требует правки]

Как на java в цикле от 0 до 1000 напечатать четные числа прописью? Есть ли где то готовое решение для получения числа прописью?

213
на google поиск появилось не существующий линки на мой сайт

на google поиск появилось не существующий линки на мой сайт

На поиске google появилось такие ссылки на мой сайт

254