Как объяснить все возможные результирующие значения StrangeLoop? - PullRequest
0 голосов
/ 20 января 2019

Учитывая "StrangeLoop" -код вроде этого:

2 Потоки проходят через цикл (каждый), и они получают и устанавливают значение объекта класса MyInteger:

Какие результаты / результаты возможны?

class MyInteger
{
    private int value;

    public synchronized int getValue()
    {
        return value;
    }

    public synchronized void setValue(int value)
    {
        this.value = value;
    }
}

public class StrangeLoop extends Thread
{
    private MyInteger data;

    public StrangeLoop(MyInteger data)
    {
        this.data = data;
    }

    public void run()
    {
        for (int i = 1; i <= 10; i++)
        {
            int local = data.getValue();
            local++;
            data.setValue(local);
        }
    }

    public static void main(String[] args)
    {
        MyInteger data = new MyInteger();
        StrangeLoop t1 = new StrangeLoop(data);
        StrangeLoop t2 = new StrangeLoop(data);
        t1.start();
        t2.start();
        try
        {
            t1.join();
            t2.join();
        }
        catch (InterruptedException e)
        {
        }
        System.out.println("Final value: " + data.getValue());
    }
}

Если один поток проходит через свой цикл после того, как другой поток уже сделал это, вывод программы должен быть Final value: 20.

Но что может пойти не так? Также возможны результаты типа 10,11, ... 19 (если ОС переключается между потоками).

Возможны значения от 10 до 20? Пока я это понимаю.

Но правильное решение этого упражнения: любое значение от 2 до 20 возможно. Я не понимаю, как 2 (например) должно быть возможно.

1 Ответ

0 голосов
/ 20 января 2019

У вас есть две темы, T1 и T2. Каждый из них сделает 10 операций чтения (10R) и 10 операций записи (10 Вт). Поскольку чтение и запись синхронизированы, вы можете гарантировать, что они не происходят параллельно; и что ранее записанное значение видно в следующем чтении любого потока.

  • T1 читает значение 0
  • T2 читает и записывает значение 9 раз (теперь значение равно 9)
  • T1 записывает значение 1

T1 теперь сделал 1R, 1W; Т2 сделал 9R, 9W.

  • T1 читает значение 1
  • T2 читает значение 1

(или наоборот: порядок этих двух не важен)

T1 сделал 2R, 1W; T2 сделал 10R, 9W.

  • T1 пишет 2, затем читает и пишет 8 раз

T1 сделал 10R, 10W.

  • T2 записывает значение 2.

T2 сделал 10R, 10W.

Окончательно записанное значение равно 2, как требуется.

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