lock
orを呼び出すlockInterruptibly
と、スレッドが次のWAITING
状態になります。
待機スレッドのスレッド状態。次のいずれかのメソッドが呼び出されたため、スレッドが待機状態になっています。
- タイムアウトなしの Object.wait
- タイムアウトなしの Thread.join
- LockSupport.park
次のコードは 4 つのスレッドを開始します。最初の 2 つ (A、B) は同じコードを実行し、lock
メソッドを介していくつかのモニターをロックします。他の 2 つ (C、D) も同じコードを実行しますが、lockInterruptibly
メソッドを介して別のモニターをロックします。
public static synchronized void dumpThreadState(List<Thread> threads) {
System.out.println("thread state dump start");
for (Thread t: threads) {
System.out.println(t.getName()+" "+t.getState());
}
System.out.println("thread state dump end\n");
}
public static void main(String[] args) throws InterruptedException {
final Lock lock = new ReentrantLock();
final Lock anotherLock = new ReentrantLock();
List<Thread> threads = new LinkedList<Thread>();
Runnable first = new Runnable() {
@Override
public void run() {
try {
lock.lock();
}
catch (Exception ex) {
System.out.println(Thread.currentThread().getName()+" processing exception "+ex.getClass().getSimpleName());
}
while (true);
}
} ;
Runnable second = new Runnable() {
@Override
public void run() {
try {
anotherLock.lockInterruptibly();
}
catch (InterruptedException ex) {
System.out.println(Thread.currentThread().getName()+" was interrupted");
}
while (true);
}
};
threads.add(new Thread(first,"A"));
threads.add(new Thread(first,"B"));
threads.add(new Thread(second,"C"));
threads.add(new Thread(second,"D"));
dumpThreadState(threads);
for (Thread t: threads) {
t.start();
}
Thread.currentThread().sleep(100);
dumpThreadState(threads);
System.out.println("interrupting " + threads.get(1).getName());
threads.get(1).interrupt();
dumpThreadState(threads);
System.out.println("interrupting " + threads.get(3).getName());
threads.get(3).interrupt();
Thread.currentThread().sleep(100);
dumpThreadState(threads);
for (Thread t: threads) {
t.join();
}
}
以下を出力します。
thread state dump start
A NEW
B NEW
C NEW
D NEW
thread state dump end
thread state dump start
A RUNNABLE
B WAITING
C RUNNABLE
D WAITING
thread state dump end
interrupting B
thread state dump start
A RUNNABLE
B WAITING
C RUNNABLE
D WAITING
thread state dump end
interrupting D
D was interrupted
thread state dump start
A RUNNABLE
B WAITING
C RUNNABLE
D RUNNABLE
thread state dump end
ご覧のとおり、メソッドでロックされたスレッドlock
は中断できませんが、メソッドでロックされたスレッドは中断lockInterruptibly
できます。
synchronized
他の例では、3 つのスレッドが開始され、最初の 2 つ (A、B) は同じコードを実行し、ブロックを介して同じモニターをロックします。3 番目のスレッドは別のモニターでロックしますが、次のwait
メソッドを介して待機します。
public static void main(String[] args) throws InterruptedException {
final Object lock = new Object();
final Object anotherLock = new Object();
List<Thread> threads = new LinkedList<Thread>();
Runnable first = new Runnable() {
@Override
public void run() {
synchronized(lock) {
while (true);
}
}
} ;
Runnable second = new Runnable() {
@Override
public void run() {
synchronized(anotherLock) {
try {
anotherLock.wait();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
};
threads.add(new Thread(first,"A"));
threads.add(new Thread(first,"B"));
threads.add(new Thread(second,"C"));
dumpThreadState(threads);
for (Thread t: threads) {
t.start();
}
Thread.currentThread().sleep(100);
dumpThreadState(threads);
for (Thread t: threads) {
t.join();
}
}
以下を出力します。
thread state dump start
A NEW
B NEW
C NEW
thread state dump end
thread state dump start
A RUNNABLE
B BLOCKED
C WAITING
thread state dump end
スレッド C は次のWAITING
状態になり、スレッド B はBLOCKING
次の状態になりました。
モニター・ロックを待ってブロックされたスレッドのスレッド状態。ブロック状態のスレッドは、監視ロックが同期ブロック/メソッドに入るのを待っているか、Object.wait を呼び出した後に同期ブロック/メソッドに再び入るのを待っています。
編集:
これは、スレッド状態の非常に優れたUML ダイアグラムです。