Получаю много просьб на продолжение серии задач по многопоточности, поэтому не останавливаемся, продолжаем. Эта задача немного попроще предыдущей.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | ** * Как остановить поток? * * Для того, чтобы прервать поток, мы можем использовать флаг * shouldTerminate, который должен проверяться в цикле внутри run(). * Если флаг становится true, мы просто выходим из цикла. * * Однако, тут могут быть проблемы, если от нашего потока зависят другие потоки. * В настоящий момент поток t2 прерывается, и программа подвисает, * т.к. поток t1 ждет второй поток и не может дождаться. * Какие есть решения проблемы? */ public class WaitTerminateTutor { Thread t1, t2; Object monitor = new Object(); int runningThreadNumber = 1; class TestThread implements Runnable { String threadName; public boolean shouldTerminate; public TestThread(String threadName) { this.threadName = threadName; } @Override public void run() { for (int i=0;i<100;i++) { System.out.println(threadName+":"+i); synchronized(monitor) { try { while (!threadName.equals("t"+runningThreadNumber)) { System.out.println("wait for thread "+"t"+runningThreadNumber); monitor.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } runningThreadNumber++; if (runningThreadNumber>2) runningThreadNumber=1; monitor.notifyAll(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } if (shouldTerminate) return; } } } } @Test public void testThread() { TestThread testThread1 = new TestThread("t1"); t1 = new Thread(testThread1); final TestThread testThread2 = new TestThread("t2"); t2 = new Thread(testThread2); System.out.println("Starting threads..."); t1.start(); t2.start(); Thread terminator = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } testThread2.shouldTerminate=true; } }); terminator.start(); System.out.println("Waiting threads to join..."); try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } |
Есть как минимум два решения, с третим потоком и без него. Попробуйте найти оба. Удачи!
Не забываем высылать результаты.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.