자바 는 두 개의 스 레 드 로 숫자 와 자 모 를 교체 인쇄 한다.
1.파 크 와 unpark
package cn.bridgeli.demo;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.concurrent.locks.LockSupport;
/**
* @author BridgeLi
* @date 2021/2/6 16:14
*/
public class Thread_Communication_Park_Unpark {
static Thread t1 = null;
static Thread t2 = null;
public static void main(String[] args) {
final List<Integer> integers = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7);
final List<String> strings = Lists.newArrayList("A", "B", "C", "D", "E", "F", "G");
t1 = new Thread(() -> integers.forEach(item -> {
System.out.print(item);
LockSupport.unpark(t2);
LockSupport.park();
}), "t1");
t2 = new Thread(() -> strings.forEach(item -> {
LockSupport.park();
System.out.print(item);
LockSupport.unpark(t1);
}), "t2");
t1.start();
t2.start();
}
}
이것 은 가장 간단 한 실현 방법 입 니 다.LockSupport.park()는 현재 스 레 드 를 막 고 LockSupport.unpark()는 스 레 드 를 깨 우 는 것 을 표시 합 니 다.그래서 그 는 어떤 스 레 드 를 깨 우 고 싶 은 지 이해 하기 쉽 고 간단 한 매개 변수 가 필요 합 니 다.2. synchronized、notify、wait
package cn.bridgeli.demo;
import com.google.common.collect.Lists;
import java.util.List;
/**
* @author BridgeLi
* @date 2021/2/6 16:14
*/
public class Thread_Communication_Notify_Wait {
public static void main(String[] args) {
final Object o = new Object();
final List<Integer> integers = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7);
final List<String> strings = Lists.newArrayList("A", "B", "C", "D", "E", "F", "G");
new Thread(() -> {
synchronized (o) {
integers.forEach(item -> {
System.out.print(item);
o.notify();
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
o.notify();
}
}, "t1").start();
new Thread(() -> {
synchronized (o) {
strings.forEach(item -> {
System.out.print(item);
o.notify();
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
o.notify();
}
}, "t2").start();
}
}
이것 은 비교적 전통 적 인 서법 이자 이해 하기 어 려 운 서법 이다.이런 서법 을 파악 한 후에 synchronized,notify,wait 에 대한 인식 도 새로운 높이 가 있 을 것 이다.다음은 이런 서법 을 간단하게 해석 해 보 자.우 리 는 모두 synchronized 가 자물쇠 라 는 것 을 알 고 있 습 니 다.자물쇠 가 무엇 입 니까?바로 제3자 가 서로 배척 하 는 자원 이다.그래서 synchronized(o)는 우리 가 o 라 는 대상 에 자 물 쇠 를 추가 한 것 은 o 의 대상 머리 를 수정 하여 이 루어 진 것 이다.즉,두 개의 스 레 드 가 o 의 대상 머리 를 성공 적 으로 수정 한 사람 이 이 자 물 쇠 를 받 은 다음 에 안의 관련 논 리 를 집행 할 수 있 고 o 의 대상 머리 스 레 드 를 성공 적 으로 수정 하지 못 했다.대상 o 의 대기 열 에 들 어가 서 시스템 에 의 해 실행 되 기 를 기다 리 는 것 만 있 습 니 다.그 다음 에 o.notify()입 니 다.방금 synchronized(o)한 무더기 의 스 레 드 가 자 물 쇠 를 빼 앗 지 못 했 습 니 다.자 물 쇠 를 빼 앗 지 못 한 스 레 드 가 대상 o 의 대기 열 에 들 어 갔 기 때문에 o.notify()의 미 는 대상 o 의 대기 열 에서 무 작위 로 스 레 드 를 깨 우 고 실행 하 는 것 입 니 다.마지막 으로 o.wait()의 의미 입 니 다.그의 의미 도 간단 합 니 다.바로 현재 스 레 드 를 대상 o 의 대기 열 에 놓 고 CPU 를 양보 하 는 것 입 니 다.
이 설명 을 통 해 자주 발생 하 는 세 가지 문제 가 어떻게 된 일 인지 배 울 수 있 습 니 다.1.wait 가 CPU 자원 을 점용 하 는 지,대기 열 에 들 어 갔 기 때문에 점용 하지 않 습 니 다.2.notify,wait 는 스 레 드 를 깨 우 고 스 레 드 를 기다 리 게 하 는 것 입 니 다.왜 Thread 류 의 방법 이 아니 라 Object 의 방법 입 니까?notify,wait 는 synchronized 와 함께 사용 되 기 때문에 다 중 스 레 드 에 사용 되 지 않 습 니 다.synchronized 잠 금 대상 의 대기 열 을 제어 하고 synchronized 잠 금 대상 을 제어 합 니 다.분명 Object 일 것 입 니 다.그래서 notify,wait,예 를 들 어 Object 대상 의 방법 입 니 다.3.synchronized(o)괄호 안에 대상 인 스 턴 스,Class 대상,잠 금 코드 블록,정적 변수 등 차이 가 있 습 니 다.synchronized 가 수정 한 것 이 무엇 인지 알 면 이러한 차 이 는 한눈 에 알 수 있 고 더 이상 군말 하지 않 습 니 다.
마지막 으로 설명 하고 자 하 는 문 제 는 바깥 을 순환 하 는 o.notify()가 없어 서 는 안 된다 는 것 이다.어떤 친구 들 은 쓸 때 손 쉽게 잊 어 버 리 거나 왜 마지막 에 notify 를 해 야 하 는 지 모 르 겠 지만 곰 곰 이 생각해 보면 알 수 있다.마지막 에 실 행 된 것 이 알파벳 을 지 는 스 레 드 라 고 가정 하면 그 는 반드시 출력 숫자의 스 레 드 에 의 해 깨 어 났 을 것 이다.출력 숫자 를 실행 하 는 이 스 레 드 는 출력 자 모 를 실행 하 는 스 레 드 를 깨 운 후에 자신 이 대기 열 에 들 어 갑 니 다.그래서 순환 이 끝 난 후에 마지막 으로 출력 자 모 를 실행 하 는 스 레 드 가 출력 숫자 를 실행 하 는 스 레 드 를 깨 우지 않 으 면 출력 숫자 를 실행 하 는 스 레 드 는 wait 가 계속 막 혀 서 황무지 에서 바닷물 이 마 르 고 돌 이 썩 을 때 까지 기다 릴 것 입 니 다.
3. Condition
package cn.bridgeli.demo;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author BridgeLi
* @date 2021/2/6 16:14
*/
public class Thread_Communication_Condition {
public static void main(String[] args) {
final List<Integer> integers = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7);
final List<String> strings = Lists.newArrayList("A", "B", "C", "D", "E", "F", "G");
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
new Thread(() -> {
lock.lock();
try {
integers.forEach(item -> {
System.out.print(item);
condition2.signal();
try {
condition1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
condition2.signal();
} finally {
lock.unlock();
}
}, "t1").start();
new Thread(() -> {
lock.lock();
try {
strings.forEach(item -> {
System.out.print(item);
condition1.signal();
try {
condition2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
condition1.signal();
} finally {
lock.unlock();
}
}, "t2").start();
}
}
우리 가 위의 두 가지 문법 을 이해 한 후에 마지막 으로 이 문법 도 사실 비교적 쉽게 이해 할 수 있 으 니 내 가 쓸데없는 말 을 할 필요 가 없다.만약 에 친구 들 이 이곳 을 보 게 된다 면 저 는 작은 문 제 를 제기 하 겠 습 니 다.어떻게 해결 해 야 할 지 생각해 볼 수 있 습 니 다.뒤의 두 가지 쓰기 방법 을 생각해 볼 수 있 습 니 다.우 리 는 출력 숫자의 스 레 드 를 실행 할 것 인지,아니면 출력 알파벳 의 스 레 드 를 먼저 실행 할 것 인 지 를 보장 합 니 다.즉,먼저 숫자 나 자 모 를 출력 하 는 것 입 니까?만약 안 된다 면 현재 업무 수요 요 구 는 알파벳 이나 숫자 를 먼저 출력 해 야 합 니 다.어떻게 해 야 합 니까?알림:CAS 자전)
이상 은 자바 가 두 개의 스 레 드 로 숫자 와 알파벳 을 교체 인쇄 하 는 상세 한 내용 입 니 다.자바 스 레 드 교체 인쇄 에 관 한 자 료 는 우리 의 다른 관련 글 을 주목 하 세 요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.