Программирование на JAVA
Меню :
Стартовая
Основы программирования
Программирование на JAVA
Программирование на C++
Программирование на Pascal
Задачи по программированию
После этого блок выполняется. При завершении исполнения (как успешном, так и в случае ошибок) производится операция unlock, чтобы освободить объект для других потоков.
Рассмотрим пример:
public class ThreadTest implements Runnable {
private static ThreadTest shared = new ThreadTest(); public void processo { for (int i=0; i<3; i++) {
System.out.println (Thread.currentThread().
getName()+" "+i); Thread.yield();
}
}
public void run() { shared. process();
10 Потоки выполнения. Синхронизация
jgKUHgJf__ --- =—=—------- —------ —
public static void main(String s[]) { for (int i=0; i<3; i++) {
new Thread(new ThreadTest(), "Thread-"+i).start();
}
}
}
В этом простом примере три потока вызывают метод у одного объекта, чтобы тот распечатал три значения. Результатом будет:
Thread-0 0 Thread-1 0 Thread-2 0 Thread-0 1 Thread-2 1 Thread-0 2 Thread-1 1 Thread-2 2 Thread-1 2
To есть все потоки одновременно работают с одним методом одного объекта. Заключим обращение к методу в synchronized-блок:
public void run() {
synchronized (shared) { shared. processO;
}
}
Теперь результат будет строго упорядочен:
Thread-0 0 Thread-0 1 Thread-0 2 Thread-1 0 Thread-1 1 Thread-1 2 Thread-2 0 Thread-2 1 Thread-2 2
Synchronized-методы работают аналогичным образом. Прежде, 4eiv начать выполнять их, поток пытается заблокировать объект, у которого вызывается метод. После выполнения блокировка снимается. В предыду шем примере аналогичной упорядоченности можно было добиться, если использовать не synchronized-блок, а объявить метод process() синхронизированным.
Также допустимы методы static synchronized. При их вызове блокировка устанавливается на объект класса Class, отвечающего за тип, у которого вызывается этот метод.
При работе с блокировками всегда надо помнить о возможности появления deadlock - взаимных блокировок, которые приводят к зависанию программы. Если один поток заблокировал один ресурс и пытается заблокировать второй, а другой поток заблокировал второй и пытается заблокировать первый, то такие потоки уже никогда не выйдут из состояния ожидания.
Рассмотрим простейший пример:
public class DeadlockDemo { //Два объекта-ресурса
public final static Object one=new Object(), two=new Object();