2016-07-27 9 views
0

У меня есть два потока t0 и t1 с runnables, указанными ниже в разделе кода Run_0 и Run1 соответственно. то, что я хочу сделать, когда t0 пишет или выполняет свою задачу, которая длится 7 секунд, t1 должен ждать. и когда истечет 7 секунд, t1 должен быть уведомлен о продолжении работы. Я попытался сделать это с помощью wait() и notify(), но во время выполнения я ожидал, что t0 начнется, но на консоли отобразится только «T1 работает», а t0 ничего не печатает, как если бы оно не было начатоwait() не заставляет поток ждать?

, пожалуйста, позвольте мне знать, почему такое поведение происходит.

код:

public static void main(String[] args) { 

    t0 = new Thread(new Run_0()); 
    t1 = new Thread(new Run_1()); 

    t0.start(); 
    t1.start(); 
} 

private static class Run_0 implements Runnable { 

    public void run() { 
     // TODO Auto-generated method stub 

     while (true) { 
      long startTime = TimeUtils.getTSSec(); 
      synchronized (t1) { 
       try { 
        t1.wait(); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 

      System.out.println("T0 is writing"); 
      //simulate doing some work 
      while((TimeUtils.getTSSec()-startTime) <= 7) { 

      } 
      System.out.println("T0 finished writing"); 

      synchronized (t1) { 
       t1.notify(); 
      } 

      startTime = TimeUtils.getTSSec(); 

      while((TimeUtils.getTSSec()-startTime) <= 7) { 

      } 
     } 

    } 

} 

private static class Run_1 implements Runnable { 

    public void run() { 
     // TODO Auto-generated method stub 

     while(true) { 

      System.out.println("T1 is working"); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

} 
+0

Возможно, вам стоит взглянуть на то, как использовать 'wait' и' notify' здесь сначала: http://www.qat.com/using-waitnotify-instead-thread-sleep-java/ – nidomiro

+0

Или здесь, https : //docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html –

ответ

0

wait, notify и notifyAll должен быть внутри synchronized блока. У вас есть один notify, который за его пределами:

 t1.notify(); // <------- 
     startTime = TimeUtils.getTSSec(); 
+0

ok исправил код и теперь t1.notify внутри синхронизированного блока, но я все равно получаю те же результаты – user2121

+0

Пока ваше утверждение правильно, он ничего не делает для решения вопроса. – bradimus

+0

@bradimus Вопрос перед редактированием ссылался на исключение, которое происходило, теперь оно было удалено, не уверен, почему (http://stackoverflow.com/posts/38612670/revisions). –

1

Из javadocs (курсив мой):

Вызывает текущий поток ждать, пока другой поток не вызывает метод notify() или метод notifyAll() для этот объект.

Ваш код вызывает t0, чтобы подождать, а не t1.

0

консоль отображает только «T1 не работает» и t0 ничего не выводит, как если бы он не был запущен

Право, потому что первая вещь в Run_0.run() является t1.wait();. Это ждет, когда кто-то позвонит t1.notify() или t1.notifyAll(). Я не вижу, чтобы никто их не называл.

Когда поток вызывает wait() на объект, он заставляет поток ждать, пока монитор на уведомляемом объекте будет уведомлен. Один поток не вызывает ожидание другого потока. Он может только ждать.

Важно понимать, что вы синхронизируете, ожидаете и уведомляете объект t1, который является потоком. Любой объект, поделен между двумя нитями будет работать, и так как мы путаться с блокировкой на объекте t0 или t1 нити, вы должны вместо этого создать конечный объект блокировки и блокировки на нем:

private final Object lock = new Object(); 

t0 является написание или выполняя свою задачу, которая длится 7 секунд, t1 должен ждать.

Так это звучит, как вы должны иметь t1.wait() в Run_1 классе а не Run_0 класса.Может Run_0 должны сделать:

// much better way to simulate time passing instead of a spin loop 
Thread.sleep(7000); 
System.out.println("T0 finished writing"); 
synchronized (lock) { 
    lock.notify(); 
} 

, а затем в Run_1 вы могли бы сделать что-то вроде:

synchronized (lock) { 
    lock.wait(); 
} 
System.out.println("T1 is working"); 

Обратите внимание, что я использую общий lock объект.

+0

я думаю Run_1 должен содержать: синхронизированный (t0) { \t \t \t \t \t \t попробовать { \t \t \t \t \t \t \t t0.wait(); \t \t \t \t \t} – user2121

+0

Не имеет значения, какой объект вы используете для пользователя @ user2121. Вам просто нужно использовать один и тот же объект в обоих потоках. Я изменю свой ответ. – Gray

+0

Я обновил свой ответ @ user2121, который пытается объяснить, что использование объектов потока запутывает ваше понимание 'object.wait()' и 'object.notify()'. Надеюсь, поможет. – Gray