2015-03-26 3 views
0

Я реализовал два потока, один для печати целых чисел и другой для печати английских алфавитов. Потоки должны работать в тандеме.Выполнение последовательного потока для печати 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
От PrintNumber 1
основной поток завершает
От PrintChar 0

+0

Не актуальная проблема, но одна из ваших петель будет перебирать в 25 раз, другой 26. –

+0

@AndyTurner: Я внесены изменения в класс, и теперь оба цикла будут повторяться 26 раз. – Albin

+0

Вы приобретаете мьютекс на 'monitor', а затем, удерживая его, ждите другого потока, который также хочет, чтобы мьютекс на' monitor' уведомлял первый поток. Я предполагаю, что у тебя тупик. –

ответ

0

Ваша главная проблема заключается в том, что вы создаете два экземпляра основного класса 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 "); 
} 
+0

Спасибо за быстрый ответ. Теперь работает. – Albin

 Смежные вопросы

  • Нет связанных вопросов^_^