java 스레드 wait, notify, notify All
주의: 이 안에 관련된 라인 조작은 모두 같은 대상입니다. 그렇지 않으면 의미가 없습니다.
(1)wait()
1. 이 방법을 호출할 때 현재 라인은 대상의 자물쇠를 가지고 있어야 한다.
2. 현재 스레드는 자물쇠를 풀고 막는다.
3. 현재 스레드가 계속 막힐 것입니다. 이 스레드가 다시 대상 자물쇠를 얻고 실행을 회복하지 않는 한.현재 라인을 복구하려면 다른 라인이 notify () 또는 notify All () 방법을 사용해서 이 대상이 잠긴 라인이 복구될 때까지 기다려야 합니다. (현재 라인이 복구될 필요는 없습니다.)
4. 이 방법은 항상 순환에서 사용된다.
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
5. 이 방법은 대상 자물쇠가 있는 라인에 호출되어야 한다. 그렇지 않으면 이상이 던진다.
(2) notify () 1. 현재 대상 자물쇠를 기다리고 있는 라인을 깨웁니다.만약 여러 개의 라인이 현재 대상 자물쇠를 기다리고 있다면, 단지 한 라인만 깨어날 것이다.
2. 깨어난 라인은 현재 라인이 대상의 자물쇠를 풀 때까지 즉시 실행하지 않습니다.
3. 이 방법은 대상 자물쇠가 있는 라인에 호출되어야 한다. 그렇지 않으면 이상이 던진다.
(3)notifyAll()
1. 현재 대상이 잠긴 모든 라인을 깨우는 것은 notify ()와 다르다.
2. 깨어난 라인은 현재 라인이 대상의 자물쇠를 풀 때까지 즉시 실행하지 않습니다.또한 깨어난 모든 라인은 공정한 경쟁을 벌여 대상을 확보하고 집행한다.
3. 이 방법은 대상 자물쇠가 있는 라인에 호출되어야 한다. 그렇지 않으면 이상이 던진다.
참고:
1. 이 세 가지 방법을 호출할 때 라인은 반드시 이 대상에 대한 자물쇠를 가져야 한다. 그렇지 않으면 Illegal Monitor State Exception 이상을 던질 것이다.보통synchronized 방법이나 블록에서 라인이 자물쇠를 가지게 됩니다.
2. notify () 와 notify All () 방법을 호출하면 깨어난 라인은 즉시 실행되지 않고 대상 자물쇠를 가진 라인이 자물쇠를 풀릴 때까지 기다려야 실행됩니다.
3. notify()와 notifyAll()의 큰 차이점은 다음과 같다. notify()는 몇 개의 라인이 막혀도 한 라인만 깨우면 다른 막힌 라인은 깨우지 않고 깨어난 라인만 실행되며 다른 막힌 라인은 계속 막힌다.notifyAll () 는 모든 막힌 라인을 깨우고, 이 라인들은 실행됩니다. (대상의 자물쇠를 얻는 전제 조건)
예는 다음과 같습니다.
package test.thread;
import java.util.ArrayList;
import java.util.List;
/**
*
*
*/
public class Test {
public static void main(String[] args) {
final Bean bean = new Bean();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 50; i++)
bean.create();
}
}).start();
for (int i = 0; i < 50; i++)
bean.use();
}
}
class Bean {
private List<String> list = new ArrayList<String>();
/**
*
*
*/
public synchronized void create() {
while (list.size() != 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < 10; i++) {
System.out.println("Create Bean:" + i);
list.add("Bean: " + i);
}
this.notify();
}
/**
*
*
*/
public synchronized void use() {
while (list.size() != 10) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while (list.size() > 0) {
System.out.println(list.remove(0));
}
this.notify();
}
}
자물쇠를 쉽게 만드는 예를 하나 더 들면 다음과 같다.
4
package test.thread;
import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Stack {
LinkedList list = new LinkedList();
public synchronized void push(Object x) {
synchronized (list) {
list.addLast(x);
notify();
}
}
public synchronized Object pop() throws Exception {
synchronized (list) {
if (list.isEmpty()) {
wait();
}
return list.removeFirst();
}
}
public static void main(String[] args) {
final Stack s = new Stack();
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Runnable() {
public void run() {
try {
System.out.println(s.pop());
} catch (Exception e) {
e.printStackTrace();
}
}
});
exec.execute(new Runnable() {
public void run() {
s.push("test");
}
});
exec.shutdown();
}
}
상례에서wait()와notify() 방법을 호출할 때 Stack 대상의 자물쇠만 풀었지만 링크드 리스트 대상의 자물쇠가 풀리지 않았을 수도 있다. 그러면 프로그램 경쟁인 링크드 리스트 대상의 자물쇠가 풀려 사라질 수 있다.이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.