Последовательное выполнение потока для печати 1A 2B 3C 4D

Я реализовал два потока: один для печати целых чисел, а другой для печати английских алфавитов. Потоки должны работать в тандеме.

Я использую синхронизированный блок, и только один поток будет удерживать блокировку за раз. Но почему-то AtomicInteger работает не так, как ожидалось. Изменения в переменной count, сделанные одним потоком, не видны другим другим потокам. Как это возможно. Я что-то упускаю?

Моя реализация

package com.concurrency;

импортировать java.util.concurrent.atomic.AtomicInteger;

открытый класс ThreadWaitEg {

// Single monitor object for both threads
private final Object monitor = new Object();
// Thread-safe counter for both threads
private final AtomicInteger count = new AtomicInteger(0);

private class PrintNumber implements Runnable 
{

    @Override
    public void run() 
    {
        for (int i = 0; i < 26; i++) 
        {
            synchronized (monitor) 
            {
                System.out.println("From PrintNumber "+count.get());
                try 
                {
                    while ((count.get()) % 2 != 0) 
                    {
                        monitor.wait();
                    }

                } catch (InterruptedException e) 
                {
                    e.printStackTrace();
                }
                System.out.println(i);
                count.getAndIncrement();
                monitor.notifyAll();

            }
        }

    }

}

private class PrintChar implements Runnable 
{

    @Override
    public void run() 
    {

        for (int charr = 'A'; charr <= 'Z'; charr++) 
        {
            synchronized (monitor) 
            {
                System.out.println("From PrintChar "+count.get());
                try 
                {
                    while ((count.get()) % 2 == 0) 
                    {
                        monitor.wait();
                    }

                } catch (InterruptedException e) 
                {
                    e.printStackTrace();
                }
                System.out.println((char) charr);
                count.getAndIncrement();
                monitor.notifyAll();
            }
        }
    }

}

public static void main(String[] args) 
{
    System.out.println("from main thread");
    Runnable runInt = new ThreadWaitEg().new PrintNumber();
    new Thread(runInt).start();
    Runnable runChar = new ThreadWaitEg().new PrintChar();
    new Thread(runChar).start();
    System.out.println(" main thread completes ");
}

}

Вывод

из основного потока
Из PrintNumber 0
0
Из PrintNumber 1
завершение основного потока
Из PrintChar 0


person Albin    schedule 26.03.2015    source источник
comment
Не фактическая проблема, но один из ваших циклов будет повторяться 25 раз, другой - 26.   -  person Andy Turner    schedule 26.03.2015
comment
@AndyTurner: я внес изменения в класс, и теперь оба цикла будут повторяться 26 раз.   -  person Albin    schedule 26.03.2015
comment
Вы получаете мьютекс на monitor, а затем, удерживая его, ждете другого потока, который также хочет, чтобы мьютекс на monitor уведомил первый поток. Я предполагаю, что у вас есть тупик.   -  person Andy Turner    schedule 26.03.2015
comment
Можно удерживать мьютекс на объекте и, удерживая его, вызывать monitor.wait(), так как это снимет блокировку и перейдет в состояние BLOCKING, ожидая сигнала от другого потока.   -  person Albin    schedule 26.03.2015


Ответы (1)


Ваша основная проблема заключается в том, что вы создаете два экземпляра основного класса ThreadWaitEg, каждый со своей собственной копией объектов «монитор» и «счетчик», поэтому объекты не используются совместно двумя потоками. Самое быстрое решение - создать только один экземпляр, т.е. заменить метод main() на:

public static void main(String[] args) {
    System.out.println("from main thread");
    ThreadWaitEg threadWaitEg = new ThreadWaitEg();
    Runnable runInt = threadWaitEg.new PrintNumber();
    new Thread(runInt).start();
    Runnable runChar = threadWaitEg.new PrintChar();
    new Thread(runChar).start();
    System.out.println(" main thread completes ");
}
person BarrySW19    schedule 26.03.2015