Download Синхронизация в Java

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Критическая секция:
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()
}
}
}
}
Related documents