2013-12-15 3 views
1

Я сделал это образец для тестирования ждать/уведомит функциональные возможности:Подождите, не таймаут

public class WaitingTest implements Runnable { 

    Thread b = new Thread(this,"query"); 
    int total=0; 

    public static void main(String[] args){ 
     WaitingTest w = new WaitingTest(); 
    } 

    public WaitingTest(){ 
     b.start(); 
      synchronized(b){ 
       try{ 
        System.out.println("Waiting for b to complete..."); 
        b.wait(10); 
       }catch(InterruptedException e){ 
        e.printStackTrace(); 
       } 
       System.out.println("Total is: " + total); 
      } 

    } 
    @Override 
    public void run(){ 

    synchronized(b){ 
      for(int i=0; i<1000000000 ; i++){ 
       total += i; 
      } 

     } 
    } 
} 

Проблема заключается в том, мой вывод должен быть равен нулю, так как Im уведомляющее ждать после 10мс и моя нить занимает больше времени, чем это выполнять свою работу. Итак, мой вывод должен быть нулевым, вместо этого он приходит к другому значению. Что мне не хватает?

EDIT:

public class WaitingTest implements Runnable { 

     Thread b = new Thread(this,"query"); 
     int total=0; 

     public static void main(String[] args){ 
      WaitingTest w = new WaitingTest(); 
     } 

     public WaitingTest(){ 
      b.start(); 
       synchronized(b){ 
        try{ 
         System.out.println("Waiting for b to complete..."); 
         b.wait(); 
        }catch(InterruptedException e){ 
         e.printStackTrace(); 
        } 
        System.out.println("Total is: " + total); 
       } 

     } 
     @Override 
     public void run(){ 

     synchronized(b){ 
      b.notify(); 
       for(long i=0; i<100000 ; i++){ 
        total += i; 
       } 

      } 
     } 
    } 
+0

Там нет необходимости добавлять основной тег в названии. –

+0

@VictorOliveira На вашем EDIT - несмотря на то, что вы теперь вызываете b.notify() перед циклом, вы все равно не можете получить нуль (в потоке печати), потому что вы еще не покинули синхронизированный блок (в расчетном потоке) , –

ответ

1

javadoc для wait() состояний

Этот метод вызывает текущий поток (назовем его T), чтобы поместить себя в набор ожидания для этого объекта, а затем отказаться от любые и все требования к синхронизации на этом объекте

Так что wh ен ты

b.wait(10); 

текущий поток освобождает synchronized он имеет на b и, следовательно, ваш другой поток может приобрести его в методе run() исходя из

b.start(); 

В total начинает увеличиваться. Когда 10 мс встает, основной поток снова блокирует b (при условии, что run() завершает) и распечатывает общее количество. Обратите внимание, что ваш total скорее всего переполнится.

+0

Я не уверен, что я получил вас, но это значит, что мой поток «b» ждет уведомления и до тех пор, пока он не выполнит ничего, после того, как таймаут Run запустится еще раз, и после того, как все закончится, он будет печатать общее значение ? (Я знаю о переполнении, но это всего лишь образец, чтобы применить идею в реальном проекте) –

+0

@victor Все зависит от планировщика потоков, но позволяет взять пример. Вызывается ваш конструктор, вы начинаете свой второй поток с 'b.start()'. Если этот поток сначала берет монитор 'b', ваш' run() 'будет завершен, потому что ваш основной поток не может получить' b'. Если основной поток сначала берет монитор 'b', он выдает сообщение, вызывает' wait (10) ', отказывается от контроля монитора' b' и помещается в зону ожидания для монитора 'b'. Ваша другая нить снова будет завершена, и в этот момент будет доступен монитор 'b' для взятия. –

+0

@Sotirios Delimanolis Он просто переполняется, это его главная проблема, а не часть синхронизации потоков. –

0

Вы получаете переполнение (вы не можете суммировать эти 1000000000 неотрицательные int и сохранить результат
в int). Определить общее количество как long. Также позвоните b.notify() или b.notifyAll()
после вашей петли в пробег способ сделан.
Кроме того, измените wait (10), чтобы просто подождать(), это заставит поток печати ждать
расчетной нити столько, сколько необходимо (а не только на 10 миллисекунд).
Это правильный способ проведения этого теста.

Что касается части синхронизации потоков, я предлагаю вам прочитать что-то, например. эти старые статьи.

http://www.javaworld.com/article/2074217/java-concurrency/java-101--understanding-java-threads--part-1--introducing-threads-and-runnables.html

http://www.javaworld.com/article/2074318/java-concurrency/java-101--understanding-java-threads--part-2--thread-synchronization.html

http://www.javaworld.com/article/2071214/java-concurrency/java-101--understanding-java-threads--part-3--thread-scheduling-and-wait-notify.html

http://www.javaworld.com/article/2074481/java-concurrency/java-101--understanding-java-threads--part-4---thread-groups--volatility--and-threa.html

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