В прошлую пятницу и выходные я сделал перерыв в своей занятой работе и рассмотрел реализацию Thread.interrupt и LockSupport после Java 5, одновременно наблюдая за параллельной работой Java.
Прежде чем представиться, позвольте мне задать несколько вопросов.
Какова связь между методом Thread.interrupt() и InterruptedException? Вызывается ли исключение InterruptedException прерыванием?
В каком состоянии Thread.interrupt() прервет работу потока? БЕГЕТ или БЛОКИРУЕТСЯ?
Нужно ли в общем программировании потоков обращать внимание на прерывания? Как с этим бороться вообще? Для чего его можно использовать?
В чем разница между LockSupport.park() и unpark(), а также object.wait() и notify()?
Какая польза от объекта блокировки, переданного LockSupport.park (блокировщик объектов)?
Может ли LockSupport реагировать на события Thread.interrupt()? Будет ли выброшено InterruptedException?
Существует ли соответствующая функция обратного вызова для обработки Thread.interrupt()? Что-то вроде звонка на крючок?
Если вы можете четко на все ответить, значит, вы уже полностью понимаете Thread.interrupt, и вам не нужно читать дальше.
Если вам все еще непонятно, давайте разберемся вместе с этими вопросами.
Несколько методов обработки прерывания Thread:
public void прерывание(): выполнить событие прерывания потока
public boolean isInterrupted() : проверяет, прерван ли текущий поток
public static логическое прерывание(): проверяет, прерван ли текущий поток, и сбрасывает информацию о прерывании. Аналогично сбросуAndGet()
понимать:
1. Каждый поток имеет флаг состояния прерывания, указывающий, находится ли текущий поток в прерванном состоянии.
2. Обычно существует два метода обработки при вызове Thread.interrupt() при обнаружении состояния блока с низким приоритетом, например object.wait(), object.sleep(), object.join(). Это немедленно вызовет разблокировку для разблокировки и выдаст InterruptedException.
В других случаях Thread.interrupt() обновляет только флаг состояния. Затем ваш рабочий поток проверяет Thread.isInterrrupted() и может выполнить соответствующую обработку, например выдачу InterruptedException или очистку статуса, отмену задачи и т. д.
Описано в javadoc по прерываниям:
лучшие практики
Есть статья про IBM, очень хорошая. Теория и практика Java: Работа с InterruptedException, в которой упоминаются несколько лучших практик обработки прерываний.
Не глотайте прерывания (не глотайте прерывания, обычно существует два типа обработки: продолжать генерировать InterruptedException. Другой — продолжать устанавливать флаг исключения Thread.interupt(), позволяя более высокому уровню обрабатывать его соответствующим образом.
Скопируйте код кода следующим образом:
публичный класс TaskRunner реализует Runnable {
частная очередь BlockingQueue<Task>;
public TaskRunner (очередь BlockingQueue<Task>) {
this.queue = очередь;
}
общественный недействительный запуск () {
пытаться {
в то время как (истина) {
Задача задача = очередь.take(10, TimeUnit.SECONDS);
задача.выполнить();
}
}
поймать (InterruptedException е) {
// Восстанавливаем прерванный статус
Thread.currentThread().interrupt();
}
}
}
Скопируйте код кода следующим образом:
публичный класс TaskRunner реализует Runnable {
частная очередь BlockingQueue<Task>;
public TaskRunner (очередь BlockingQueue<Task>) {
this.queue = очередь;
}
общественный недействительный запуск () {
пытаться {
в то время как (истина) {
Задача задача = очередь.take(10, TimeUnit.SECONDS);
задача.выполнить();
}
}
поймать (InterruptedException е) {
// Восстанавливаем прерванный статус
Thread.currentThread().interrupt();
}
}
}
Реализация отменяемых задач с помощью Interrupt (используйте Thread.interrupt() для разработки и поддержки задач, которые можно отменить)
Скопируйте код кода следующим образом:
публичный класс PrimeProducer расширяет поток {
частная финальная очередь BlockingQueue<BigInteger>;
PrimeProducer (очередь BlockingQueue<BigInteger>) {
this.queue = очередь;
}
общественный недействительный запуск () {
пытаться {
BigInteger p = BigInteger.ONE;
в то время как (!Thread.currentThread().isInterrupted())
очередь.put(p = p.nextProbablePrime());
} catch (использовано InterruptedException) {
/* Разрешить потоку выйти */
}
}
public void cancel() { прерывание() } // Инициируем прерывание
</SPAN style="WHITE-SPACE: нормальный"> </SPAN>
Скопируйте код кода следующим образом:
публичный класс PrimeProducer расширяет поток {
частная финальная очередь BlockingQueue<BigInteger>;
PrimeProducer (очередь BlockingQueue<BigInteger>) {
this.queue = очередь;
}
общественный недействительный запуск () {
пытаться {
BigInteger p = BigInteger.ONE;
в то время как (!Thread.currentThread().isInterrupted())
очередь.put(p = p.nextProbablePrime());
} catch (использовано InterruptedException) {
/* Разрешить потоку выйти */
}
}
public void cancel() { прерывание() } // Инициируем прерывание
</SPAN style="WHITE-SPACE: нормальный"> </SPAN>
Зарегистрировать событие обработки прерывания (ненормальное использование)
Как правило, обычные задачи предназначены для обработки отмены, и все они используют активный опрос для проверки Thread.isInterrupt(), который имеет определенную степень встроенности в сам бизнес, а также существует задержка. Приходится ждать следующего. контрольная точка (кто знает, когда следующая контрольная точка? Особенно при выполнении Socket.read я столкнулся с проблемой тайм-аута HttpClient).
Давайте посмотрим. Реализация активного создания InterruptedException основана на конструкции InterruptibleChannel, которая довольно умна.
Скопируйте код кода следующим образом:
интерфейс InterruptAble { // Определить прерываемый интерфейс
public void прерывание() выдает InterruptedException;
}
абстрактный класс InterruptSupport реализует InterruptAble {
частное изменчивое логическое значение прерывается = ложь;
частный прерываемый прерыватель = новый Interruptible() {
общественное недействительное прерывание () {
прервано = правда;
InterruptSupport.this.interrupt(); // Позиция 3
}
};
public Final boolean Execute() выдает InterruptedException {
пытаться {
заблокированВкл(прерыватель); // Позиция 1
if (Thread.currentThread().isInterrupted()) { // Немедленно прерывается
прерыватель.прерывание();
}
//Выполняем бизнес-код
бизнес();
} окончательно {
заблокированВкл(нуль); // Позиция 2
}
возврат прерван;
}
публичный абстрактный void business() ;
публичное абстрактное недействительное прерывание ();
// -- sun.misc.SharedSecrets --
static voidblockOn(Interruptible intr) { // приватный пакет
sun.misc.SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(), intr);
}
}
Скопируйте код кода следующим образом:
интерфейс InterruptAble { // Определить прерываемый интерфейс
public void прерывание() выдает InterruptedException;
}
абстрактный класс InterruptSupport реализует InterruptAble {
частное изменчивое логическое значение прерывается = ложь;
частный прерываемый прерыватель = новый Interruptible() {
общественное недействительное прерывание () {
прервано = правда;
InterruptSupport.this.interrupt(); // Позиция 3
}
};
public Final boolean Execute() выдает InterruptedException {
пытаться {
заблокированВкл(прерыватель); // Позиция 1
if (Thread.currentThread().isInterrupted()) { // Немедленно прерывается
прерыватель.прерывание();
}
//Выполняем бизнес-код
бизнес();
} окончательно {
заблокированВкл(нуль); // Позиция 2
}
возврат прерван;
}
публичный абстрактный void business() ;
публичное абстрактное недействительное прерывание ();
// -- sun.misc.SharedSecrets --
static voidblockOn(Interruptible intr) { // приватный пакет
sun.misc.SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(), intr);
}
}
Описание кода, несколько хитростей:
Позиция 1: используйте методblockOn, предоставленный sun, чтобы привязать соответствующий крючок обработки событий Interruptible к указанному потоку.
Позиция 2: После выполнения кода очистите хук. Избегайте влияния на следующее событие обработки потока при использовании пула соединений.
Позиция 3: определяет метод обработки прерываемого события и вызывает метод InterruptSupport.this.interrupt(). Подклассы могут интегрировать и реализовывать свою собственную бизнес-логику, например закрытие потока Sock и т. д.
использовать:
Скопируйте код кода следующим образом:
класс InterruptRead расширяет InterruptSupport {
частный FileInputStream в;
@Override
общественный недействительный бизнес () {
File file = new File("/dev/urandom"); // Читаем черную дыру Linux, никогда не заканчиваем чтение
пытаться {
в = новый FileInputStream (файл);
байт[] байт = новый байт[1024];
while (in.read(bytes, 0, 1024) > 0) {
// Thread.sleep(100);
// if (Thread.interrupted()) {// Метод проверки предыдущего прерывания
// выбрасываем новое InterruptedException("");
// }
}
} catch (Исключение е) {
выдать новое RuntimeException(e);
}
}
общественный FileInputStream getIn() {
вернуться;
}
@Override
общественное недействительное прерывание () {
пытаться {
in.getChannel().close();
} catch (IOException e) {
е.printStackTrace();
}
}
}
public static void main(String args[]) выдает исключение {
окончательный тест InterruptRead = новый InterruptRead();
Поток t = новый поток() {
@Override
общественный недействительный запуск () {
длинный старт = System.currentTimeMillis();
пытаться {
System.out.println("Начало прерывания чтения!");
тест.выполнить();
} catch (InterruptedException e) {
System.out.println("InterruptRead end! Стоимость времени: " + (System.currentTimeMillis() - start));
е.printStackTrace();
}
}
};
т.старт();
// Пусть чтение сначала выполняется в течение 3 секунд
Thread.sleep(3000);
//выдаем прерывание
т.прерывание();
}
Скопируйте код кода следующим образом:
класс InterruptRead расширяет InterruptSupport {
частный FileInputStream в;
@Override
общественный недействительный бизнес () {
File file = new File("/dev/urandom"); // Читаем черную дыру Linux, никогда не заканчиваем чтение
пытаться {
в = новый FileInputStream (файл);
байт[] байт = новый байт[1024];
while (in.read(bytes, 0, 1024) > 0) {
// Thread.sleep(100);
// if (Thread.interrupted()) {// Метод проверки предыдущего прерывания
// выбрасываем новое InterruptedException("");
// }
}
} catch (Исключение е) {
выдать новое RuntimeException(e);
}
}
общественный FileInputStream getIn() {
вернуться;
}
@Override
общественное недействительное прерывание () {
пытаться {
in.getChannel().close();
} catch (IOException e) {
е.printStackTrace();
}
}
}
public static void main(String args[]) выдает исключение {
окончательный тест InterruptRead = новый InterruptRead();
Поток t = новый поток() {
@Override
общественный недействительный запуск () {
длинный старт = System.currentTimeMillis();
пытаться {
System.out.println("Начало прерывания чтения!");
тест.выполнить();
} catch (InterruptedException e) {
System.out.println("InterruptRead end! Стоимость времени: " + (System.currentTimeMillis() - start));
е.printStackTrace();
}
}
};
т.старт();
// Пусть чтение сначала выполняется в течение 3 секунд
Thread.sleep(3000);
//выдаем прерывание
т.прерывание();
}
введение исходного кода jdk:
1. Крючок, предоставленный sun, позволяет просмотреть соответствующий код системы, строка: 1125.
Скопируйте код кода следующим образом:
sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess(){
public sun.reflect.ConstantPool getConstantPool(Класс класса) {
вернуть класс.getConstantPool();
}
public void setAnnotationType (класс класса, тип AnnotationType) {
класс.setAnnotationType(тип);
}
public AnnotationType getAnnotationType (класс класса) {
вернуть класс.getAnnotationType();
}
общедоступный <E расширяет Enum<E>>
E[] getEnumConstantsShared(Class<E> класс) {
return klass.getEnumConstantsShared();
}
public voidblockOn(Thread t, Interruptible b) {
т.blockedOn(б);
}
});
Скопируйте код кода следующим образом:
sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess(){
public sun.reflect.ConstantPool getConstantPool(Класс класса) {
вернуть класс.getConstantPool();
}
public void setAnnotationType (класс класса, тип AnnotationType) {
класс.setAnnotationType(тип);
}
public AnnotationType getAnnotationType (класс класса) {
вернуть класс.getAnnotationType();
}
общедоступный <E расширяет Enum<E>>
E[] getEnumConstantsShared(Class<E> класс) {
return klass.getEnumConstantsShared();
}
public voidblockOn(Thread t, Interruptible b) {
т.blockedOn(б);
}
});
2. Поток.прерывание()
Скопируйте код кода следующим образом:
общественное недействительное прерывание () {
если (это != Thread.currentThread())
проверитьДоступ();
синхронизировано (blockerLock) {
Прерываемый b = блокировщик;
если (б != ноль) {
прерывание0(); // Просто чтобы установить флаг прерывания
b.interrupt(); //Обратный вызов
возвращаться;
}
}
прерывание0();
}
Скопируйте код кода следующим образом:
общественное недействительное прерывание () {
если (это != Thread.currentThread())
проверитьДоступ();
синхронизировано (blockerLock) {
Прерываемый b = блокировщик;
если (б != ноль) {
прерывание0(); // Просто чтобы установить флаг прерывания
b.interrupt(); //Обратный вызов
возвращаться;
}
}
прерывание0();
}
Для получения дополнительной информации об использовании Thread.stop, приостановке, возобновлении и прерывании вы можете просмотреть документацию Sun, например http://download.oracle.com/javase/6/docs/technotes/guides/concurrency. /threadPrimitiveDeprecation .html
Наконец, давайте ответим на некоторые предыдущие вопросы:
Вопрос 1. Какова связь между методом Thread.interrupt() и InterruptedException? Вызывается ли исключение InterruptedException прерыванием?
Ответ: Thread.interrupt() активно генерирует InterruptedException только в Object.wait(), .Object.join() и Object.sleep(). Это распространено в других блоках, просто устанавливая информацию о флаге Thread, и программе необходимо обработать ее самостоятельно.
Скопируйте код кода следующим образом:
if (Thread.interrupted()) // Очищает статус прерывания!
выбросить новое InterruptedException();
Скопируйте код кода следующим образом:
if (Thread.interrupted()) // Очищает статус прерывания!
выбросить новое InterruptedException();
Вопрос 2: В каком состоянии Thread.interrupt() прервет работу потока? БЕГЕТ или БЛОКИРУЕТСЯ?
Ответ: Целью конструкции Thread.interrupt является главным образом обработка потоков в состоянии блока, например, в состояниях wait() и Sleep(). Однако отмена задачи может поддерживаться во время разработки программы, а также может поддерживаться состояние ВЫПОЛНЕНИЕ. Например, Object.join() и некоторые конструкции каналов nio, поддерживающие прерывания.
Вопрос 3: Нужно ли в общем программировании потоков обращать внимание на прерывания? Как с этим бороться вообще? Для чего его можно использовать?
Ответ: Использование прерываний: разблокировка операции, поддержка отмены задачи, очистка данных и т. д.
Вопрос 4. В чем разница между LockSupport.park() и unpark(), а также object.wait() и notify()?
отвечать:
1. Предметы разные. LockSuport в основном выполняет обработку блокировки для потока. Он может указать целевой объект очереди блокировки и указать конкретный поток для пробуждения каждый раз. Object.wait() принимает объект в качестве измерения, блокирует текущий поток и пробуждает один (случайный) или все потоки.
2. Механизмы реализации разные. Хотя LockSuport может указать объект монитора, очереди блокировки LockSuport и object.wait() не пересекаются. Вы можете посмотреть тестовый пример. object.notifyAll() не может разбудить блокирующий поток LockSupport.
Вопрос 5. Какова польза объекта блокировки, переданного LockSupport.park (блокировщик объектов)?
Ответ: Соответствующий блокировщик будет записан в атрибуте parkBlocker потока. Очень удобно отслеживать конкретные объекты блокировки через команду jstack.
Скопируйте код кода следующим образом:
public static void park (блокировщик объектов) {
Поток t = Thread.currentThread();
setBlocker(t,blocker); //Устанавливаем значение свойства Thread.parkBlocker;
unsafe.park(ложь, 0L);
setBlocker(t, null); // Очищаем значение свойства Thread.parkBlocker;
}
Скопируйте код кода следующим образом:
public static void park (блокировщик объектов) {
Поток t = Thread.currentThread();
setBlocker(t,blocker); //Устанавливаем значение свойства Thread.parkBlocker;
unsafe.park(ложь, 0L);
setBlocker(t, null); // Очищаем значение свойства Thread.parkBlocker;
}
Конкретное описание LockSupport в Javadoc также относительно понятно. Вы можете прочитать его ниже:
Вопрос 6. Может ли LockSupport реагировать на события Thread.interrupt()? Будет ли выброшено InterruptedException?
Ответ: Он может реагировать на события прерывания, но не генерирует InterruptedException. Что касается поддержки LockSupport для Thread.interrupte, также взгляните на описание в javadoc:
Соответствующий тестовый код
Скопируйте код кода следующим образом:
пакет com.agapple.cocurrent;
импортировать java.io.File;
импортировать java.io.FileInputStream;
импортировать java.lang.reflect.Field;
импортировать java.util.concurrent.TimeUnit;
импортировать java.util.concurrent.locks.LockSupport;
общественный класс LockSupportTest {
частный статический блокировщик LockSupportTest = новый LockSupportTest();
public static void main(String args[]) выдает исключение {
LockSupportTest();
паркТест();
ПрерываниеПаркТест();
ПрерываниеСлипТест();
ПрерываниеWaitTest();
}
/**
* После объекта LockSupport.park попробуйте получить объект Thread.blocker и вызвать его однократное пробуждение.
*
* @throwsException
*/
Private static void lockSupportTest() выдает исключение {
Поток t = doTest(new TestCallBack() {
@Override
public void callback() выдает исключение {
// пробуем спать 5 секунд
System.out.println("блокировщик");
LockSupport.park(блокировщик);
System.out.println("Просыпайтесь сейчас!");
}
@Override
публичная строка getName() {
вернуть «lockSupportTest»;
}
});
t.start(); // Запускаем поток чтения
Thread.sleep(150);
синхронизированный (блокировщик) {
Поле поля = Thread.class.getDeclaredField("parkBlocker");
поле.setAccessible(истина);
Объект fBlocker = field.get(t);
System.out.println(блокировщик == fBlocker);
Thread.sleep(100);
System.out.println("notifyAll");
блокировщик.notifyAll();
}
}
/**
* Если вы попытаетесь прервать функцию object.wait(), будет выброшено соответствующее InterruptedException.
*
* @throws InterruptedException
*/
Private static void прерываниеWaitTest() выдает InterruptedException {
конечный объект obj = новый объект();
Поток t = doTest(new TestCallBack() {
@Override
public void callback() выдает исключение {
// пробуем спать 5 секунд
объект.ожидание();
System.out.println("Просыпайтесь сейчас!");
}
@Override
публичная строка getName() {
вернуть «interruptWaitTest»;
}
});
t.start(); // Запускаем поток чтения
Thread.sleep(2000);
t.interrupt(); // Проверяем, отреагировали ли на прерывание во время парковки
}
/**
* Если вы попытаетесь прервать Thread.sleep(), будет выброшено соответствующее InterruptedException.
*
* @throws InterruptedException
*/
Private static void прерываниеSleepTest() выдает InterruptedException {
Поток t = doTest(new TestCallBack() {
@Override
public void callback() выдает исключение {
// пробуем спать 5 секунд
Thread.sleep(5000);
System.out.println("Просыпайтесь сейчас!");
}
@Override
публичная строка getName() {
вернуть «interruptSleepTest»;
}
});
t.start(); // Запускаем поток чтения
Thread.sleep(2000);
t.interrupt(); // Проверяем, отреагировали ли на прерывание во время парковки
}
/**
* Попробуйте прервать LockSupport.park(), ответ будет, но исключение InterruptedException не будет выдано.
*
* @throws InterruptedException
*/
Private static void прерываниеParkTest() выдает InterruptedException {
Поток t = doTest(new TestCallBack() {
@Override
публичный недействительный обратный вызов() {
//Попробуем припарковать свой поток
LockSupport.parkNanos(блокировщик, TimeUnit.SECONDS.toNanos(5));
System.out.println("Просыпайтесь сейчас!");
}
@Override
публичная строка getName() {
вернуть «прерываниеПаркТест»;
}
});
t.start(); // Запускаем поток чтения
Thread.sleep(2000);
t.interrupt(); // Проверяем, отреагировали ли на прерывание во время парковки
}
/**
* Попробуйте прервать вызов LockSupport.unPark(), будет ответ
*
* @throws InterruptedException
*/
Private static void parkTest() выдает InterruptedException {
Поток t = doTest(new TestCallBack() {
@Override
публичный недействительный обратный вызов() {
//Попробуем припарковать свой поток
LockSupport.park(блокировщик);
System.out.println("Просыпайтесь сейчас!");
}
@Override
публичная строка getName() {
вернуть «parkTest»;
}
});
t.start(); // Запускаем поток чтения
Thread.sleep(2000);
LockSupport.unpark(т);
т.прерывание();
}
public static Thread doTest (окончательный вызов TestCallBack) {
вернуть новый поток() {
@Override
общественный недействительный запуск () {
File file = new File("/dev/urandom" // Чтение черной дыры Linux
пытаться {
FileInputStream в = новый FileInputStream (файл);
байт[] байт = новый байт[1024];
while (in.read(bytes, 0, 1024) > 0) {
если (Thread.interrupted()) {
выбросить новое InterruptedException("");
}
System.out.println(байты[0]);
Thread.sleep(100);
длинный старт = System.currentTimeMillis();
вызов.обратный вызов();
System.out.println(call.getName() + "стоимость завершения обратного вызова: "
+ (System.currentTimeMillis() - старт));
}
} catch (Исключение е) {
е.printStackTrace();
}
}
};
}
}
интерфейс TestCallBack {
public void callback() выдает исключение;
общедоступная строка getName();
}
Скопируйте код кода следующим образом:
пакет com.agapple.cocurrent;
импортировать java.io.File;
импортировать java.io.FileInputStream;
импортировать java.lang.reflect.Field;
импортировать java.util.concurrent.TimeUnit;
импортировать java.util.concurrent.locks.LockSupport;
общественный класс LockSupportTest {
частный статический блокировщик LockSupportTest = новый LockSupportTest();
public static void main(String args[]) выдает исключение {
LockSupportTest();
паркТест();
ПрерываниеПаркТест();
ПрерываниеСлипТест();
ПрерываниеWaitTest();
}
/**
* После объекта LockSupport.park попробуйте получить объект Thread.blocker и вызвать его однократное пробуждение.
*
* @throwsException
*/
Private static void lockSupportTest() выдает исключение {
Поток t = doTest(new TestCallBack() {
@Override
public void callback() выдает исключение {
// пробуем спать 5 секунд
System.out.println("блокировщик");
LockSupport.park(блокировщик);
System.out.println("Просыпайтесь сейчас!");
}
@Override
публичная строка getName() {
вернуть «lockSupportTest»;
}
});
t.start(); // Запускаем поток чтения
Thread.sleep(150);
синхронизированный (блокировщик) {
Поле поля = Thread.class.getDeclaredField("parkBlocker");
поле.setAccessible(истина);
Объект fBlocker = field.get(t);
System.out.println(блокировщик == fBlocker);
Thread.sleep(100);
System.out.println("notifyAll");
блокировщик.notifyAll();
}
}
/**
* Если вы попытаетесь прервать функцию object.wait(), будет выброшено соответствующее InterruptedException.
*
* @throws InterruptedException
*/
Private static void прерываниеWaitTest() выдает InterruptedException {
конечный объект obj = новый объект();
Поток t = doTest(new TestCallBack() {
@Override
public void callback() выдает исключение {
// пробуем спать 5 секунд
объект.ожидание();
System.out.println("Просыпайтесь сейчас!");
}
@Override
публичная строка getName() {
вернуть «interruptWaitTest»;
}
});
t.start(); // Запускаем поток чтения
Thread.sleep(2000);
t.interrupt(); // Проверяем, отреагировали ли на прерывание во время парковки
}
/**
* Если вы попытаетесь прервать Thread.sleep(), будет выброшено соответствующее InterruptedException.
*
* @throws InterruptedException
*/
Private static void прерываниеSleepTest() выдает InterruptedException {
Поток t = doTest(new TestCallBack() {
@Override
public void callback() выдает исключение {
// пробуем спать 5 секунд
Thread.sleep(5000);
System.out.println("Просыпайтесь сейчас!");
}
@Override
публичная строка getName() {
вернуть «interruptSleepTest»;
}
});
t.start(); // Запускаем поток чтения
Thread.sleep(2000);
t.interrupt(); // Проверяем, отреагировали ли на прерывание во время парковки
}
/**
* Попробуйте прервать LockSupport.park(), ответ будет, но исключение InterruptedException не будет выдано.
*
* @throws InterruptedException
*/
Private static void прерываниеParkTest() выдает InterruptedException {
Поток t = doTest(new TestCallBack() {
@Override
публичный недействительный обратный вызов() {
//Попробуем припарковать свой поток
LockSupport.parkNanos(блокировщик, TimeUnit.SECONDS.toNanos(5));
System.out.println("Просыпайтесь сейчас!");
}
@Override
публичная строка getName() {
вернуть «прерываниеПаркТест»;
}
});
t.start(); // Запускаем поток чтения
Thread.sleep(2000);
t.interrupt(); // Проверяем, отреагировали ли на прерывание во время парковки
}
/**
* Попробуйте прервать вызов LockSupport.unPark(), будет ответ
*
* @throws InterruptedException
*/
Private static void parkTest() выдает InterruptedException {
Поток t = doTest(new TestCallBack() {
@Override
публичный недействительный обратный вызов() {
//Попробуем припарковать свой поток
LockSupport.park(блокировщик);
System.out.println("Просыпайтесь сейчас!");
}
@Override
публичная строка getName() {
вернуть «parkTest»;
}
});
t.start(); // Запускаем поток чтения
Thread.sleep(2000);
LockSupport.unpark(т);
т.прерывание();
}
public static Thread doTest (окончательный вызов TestCallBack) {
вернуть новый поток() {
@Override
общественный недействительный запуск () {
File file = new File("/dev/urandom" // Чтение черной дыры Linux
пытаться {
FileInputStream в = новый FileInputStream (файл);
байт[] байт = новый байт[1024];
while (in.read(bytes, 0, 1024) > 0) {
если (Thread.interrupted()) {
выбросить новое InterruptedException("");
}
System.out.println(байты[0]);
Thread.sleep(100);
длинный старт = System.currentTimeMillis();
вызов.обратный вызов();
System.out.println(call.getName() + "стоимость завершения обратного вызова: "
+ (System.currentTimeMillis() - старт));
}
} catch (Исключение е) {
е.printStackTrace();
}
}
};
}
}
интерфейс TestCallBack {
public void callback() выдает исключение;
общедоступная строка getName();
}
В конце концов, <BR>я обнаружил, что статья становится все длиннее и длиннее, поэтому я просто разместил ее на форуме, чтобы все могли обсудить ее вместе. В конце концов, в статье описывались только некоторые вещи на уровне использования, а не были представлены темы из операционной системы. Система или собственная реализация Sun. Для некоторых механизмов Daniumen, знакомые с этой областью, также могут высказать свое мнение.