Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Критическая секция: synchronized(obj) { // захват монитора объекта obj …. // этот код не может исполняться в нескольких потоках одновременно } // монитор объекта obj освобождание public synchronized void test(){ // захват монитора объекта, у которого вызывается метод … // этот метод не может исполняться в нескольких потоках одновременно } // монитора объекта, у которого вызывается метод, освобожден Использование монитора объекта synchronized (obj) { // захват монитора объекта obj try { obj.wait(); // поток освобождает монитор и застывает в этой точке … // этот код выполнится после того, как другой поток скажет obj.notify() } catch (InterruptedException e) { // если поток разбудили через метод interrupt(); } } synchronized (obj) { // захват монитора объекта obj obj.notify(); // посылка сообщения потоку, который первый вызвал obj.wait() и все еще ждет } synchronized (obj) { // захват монитора объекта obj obj.notifyAll(); // посылка сообщения всем потокам, которые вызвали в obj.wait() } Пример Управляемый таймер, выполняющий команды start/pause/quit package ru.nsu.fit.threadtest; import java.io.*; public class ManagedTimer implements Runnable{ private int num; private Thread thread; private boolean paused; private ManagedTimer() { this.num = 0; this.paused = true; this.thread = new Thread(this); this.thread.start(); } public void run() { while(true) { try { synchronized (this) { if (paused) { this.wait(); } } System.out.println(num++); Thread.sleep(2000); // each 2 seconds } catch (InterruptedException e) { break; } } } public synchronized void start() { paused = false; this.notifyAll(); } public synchronized void pause() { paused = true; } public synchronized void stop() { thread.interrupt(); } private Object getState() { if (thread.isAlive()) { if (paused) { return "paused"; } else { return "working"; } } else { return "stopped"; } } public static void main(String args[]) throws IOException { ManagedTimer timer = new ManagedTimer(); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); while (true) { String command = in.readLine(); if (command.startsWith("q")) { timer.stop(); break; } else if (command.startsWith("s")) { timer.start(); } else if (command.startsWith("p")) { timer.pause(); } else if (command.startsWith("i")) { System.out.println("State: "+timer.getState()); } } } } Deadlock Ситуация, когда два потока ожидают друг друга. Задание: написать такую программу. Синхронизация необходима даже для примитивных операций public class ErrorSyncTest { private long field; public void inc() { field++; } public void dec() { field--; } public class IncDecThread extends Thread { private int num; private boolean inc; public IncDecThread(int num, boolean inc) { super(); this.num = num; this.inc = inc; } public void run() { for (int i=0; i<num; i++) { if (inc) { inc(); } else { dec(); } } } } public static void main(String args[]) throws Exception { ErrorSyncTest test = new ErrorSyncTest(); ErrorSyncTest.IncDecThread[] threads = new ErrorSyncTest.IncDecThread[10]; for (int i=0; i<threads.length; i++) { threads[i] = test.new IncDecThread(1000000, i%2 == 0); } for (int i=0; i<threads.length; i++) { threads[i].start(); } for (int i=0; i<threads.length; i++) { threads[i].join(); } System.out.println("Result: "+test.field); } } Новые возможности JSDK 1.5 – использование Lock class X { private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock() } } } class X2 { private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { if (lock.tryLock()) { // block only if it isn’t locked by another thread try { // ... method body } finally { lock.unlock() } } } } class X2 { private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { if (lock.tryLock(10, TimeUnit.SECONDS)) { // block only if it isn’t locked by another thread, wait 10 seconds for this condition try { // ... method body } finally { lock.unlock() } } } }