자바 다 중 스 레 드 학습 의 잠 금 시 뮬 레이 션 과 피하 기(인 스 턴 스 설명)
잠 금 은 이러한 상황 입 니 다.여러 스 레 드 가 동시에 막 히 고 그들 중 하나 또는 모두 특정한 자원 이 방출 되 기 를 기다 리 고 있 습 니 다.스 레 드 가 무기한 으로 막 혀 있 기 때문에 프로그램 이 정상적으로 종 료 될 수 없다.
자바 잠 금 생 성 에 필요 한 네 가지 조건:
1.상호 배척 사용,즉 자원 이 하나의 스 레 드 에 의 해 사용(점유)되 었 을 때 다른 스 레 드 는 사용 할 수 없습니다.
2.선점 할 수 없고 자원 요구 자 는 자원 점유 자 에 게 서 자원 을 강제로 빼 앗 을 수 없 으 며 자원 은 자원 점유 자 에 의 해 자발적으로 방출 될 수 밖 에 없다.
3.요청 과 유지,즉 자원 요구 자가 다른 자원 을 요청 하 는 동시에 기 존 자원 에 대한 점 유 를 유지 하 는 것 이다.
4.순환 대기 열 이 존재 합 니 다.P1 은 P2 의 자원 을 차지 하고 P2 는 P3 의 자원 을 차지 하 며 P3 는 P1 의 자원 을 차지 합 니 다.이렇게 해서 대기 순환 도로 가 형성 되 었 다.
상술 한 네 가지 조건 이 모두 성립 될 때,바로 자물쇠 가 형성 된다.물론 자물쇠 가 잠 긴 상태 에서 상술 한 어떤 조건 을 깨 뜨리 면 자물쇠 가 사라 질 수 있다.
2.자물쇠 시 뮬 레이 션
package com.tl.skyLine.thread;
import java.util.Date;
/**
* Created by tl on 17/3/3.
*/
public class DeadLock {
public static String bowl = " ";
public static String chopsticks = " ";
public static void main(String[] args) {
LockA la = new LockA();
new Thread(la).start();
LockB lb = new LockB();
new Thread(lb).start();
}
}
class LockA implements Runnable {
public void run() {
try {
System.out.println(new Date().toString() + " ");
while (true) {
synchronized (DeadLock.bowl) {
System.out.println(new Date().toString() + " ");
Thread.sleep(3000); // B
synchronized (DeadLock.chopsticks) {
System.out.println(new Date().toString() + " ");
Thread.sleep(60 * 1000); // ,
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class LockB implements Runnable {
public void run() {
try {
System.out.println(new Date().toString() + " ");
while (true) {
synchronized (DeadLock.chopsticks) {
System.out.println(new Date().toString() + " ");
Thread.sleep(3000); // A
synchronized (DeadLock.bowl) {
System.out.println(new Date().toString() + " ");
Thread.sleep(60 * 1000); // ,
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
결과:
Fri Mar 03 16:34:36 CST 2017
Fri Mar 03 16:34:37 CST 2017
Fri Mar 03 16:34:36 CST 2017
Fri Mar 03 16:34:37 CST 2017
결국 천정 천 학생 은 삼 젓가락 을 빼 앗 아 놓 지 않 았 습 니 다.추 보건 학생 은 그릇 을 빼 앗 았 습 니 다.죽어도 놓 지 않 았 습 니 다.하지만 젓가락 한 켤레 와 그릇 한 켤레 만 있 었 습 니 다.결국 둘 다 굶 어 죽 었 습 니 다.3.고정 자물쇠 피하 기
만약 우리 가 천정 천 과 추 보건 학우 의 동료 라면 그들 이 굶 어 죽 는 것 을 차 마 볼 수 없 을 것 이다.그러면 어떻게 할 까?
우 리 는 사색 의 발생 을 피 하 는 방법 을 취해 야 한다.여기 서 두 가지 방법 을 소개 한다.하 나 는 잠 금 순서(스 레 드 는 일정한 순서에 따라 잠 금)이다.다른 하 나 는 잠 금 시한 을 추가 하 는 것 이다.
3.1 잠 금 추가 순서
여러 스 레 드 가 같은 자 물 쇠 를 필요 로 하지만 서로 다른 순서에 따라 자 물 쇠 를 추가 하면 자물쇠 가 쉽게 발생 한다.모든 스 레 드 가 같은 순서 로 자 물 쇠 를 얻 을 수 있다 면 잠 금 은 일어나 지 않 을 것 이다.우리 위의 코드 는 자 물 쇠 를 모 의 하기 위해 스 레 드 LockA 와 LockB 두 동료의 자원 쟁탈 순 서 를 조정 했다.LockA 는 먼저 그릇 을 빼 앗 은 다음 에 sleep 3 초 동안 LockB 는 먼저 젓가락 을 빼 앗 았 다.우 리 는 지금 자원 쟁탈 순 서 를 바 꾸 었 다.두 스 레 드 는 모두 먼저 그릇 을 빼 앗 고 젓가락 을 빼 앗 으 며 이 순서에 따라 엄 격 히 운행 한다.그러면 A 가 그릇 을 빼 앗 은 후에 B 는 자원 을 쟁탈 한다.그릇 을 빼 앗 는 것 부터 시작 해 야 한다.그릇 을 빼 앗 지 못 하 는 상황 에서 젓가락 을 빼 앗 으 면 자물쇠 가 생기 지 않도록 하 는 것 도 자물쇠 가 생기 지 않도록 하 는 가장 간단 한 방법 이다.
코드 수정 은 다음 과 같 습 니 다.
/**
* Created by tl on 17/3/3.
*/
public class UnDeadLock {
public static String bowl = " ";
public static String chopsticks = " ";
public static void main(String[] args) {
LockA la = new LockA();
new Thread(la).start();
LockB lb = new LockB();
new Thread(lb).start();
}
}
class LockA implements Runnable {
public void run() {
try {
System.out.println(new Date().toString() + " ");
while (true) {
synchronized (UnDeadLock.bowl) {
System.out.println(new Date().toString() + " ");
synchronized (UnDeadLock.chopsticks) {
System.out.println(new Date().toString() + " ");
}
}
Thread.sleep(5000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class LockB implements Runnable {
public void run() {
try {
System.out.println(new Date().toString() + " ");
while (true) {
synchronized (UnDeadLock.bowl) {
System.out.println(new Date().toString() + " ");
synchronized (UnDeadLock.chopsticks) {
System.out.println(new Date().toString() + " ");
}
}
Thread.sleep(5000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
실행 결과
Fri Mar 24 11:16:51 CST 2017
Fri Mar 24 11:16:51 CST 2017
Fri Mar 24 11:16:51 CST 2017
Fri Mar 24 11:16:51 CST 2017
Fri Mar 24 11:16:51 CST 2017
Fri Mar 24 11:16:51 CST 2017
Fri Mar 24 11:16:56 CST 2017
Fri Mar 24 11:16:56 CST 2017
Fri Mar 24 11:16:56 CST 2017
Fri Mar 24 11:16:56 CST 2017
Fri Mar 24 11:17:01 CST 2017
Fri Mar 24 11:17:01 CST 2017
다 시 는 자물쇠 가 잠 겨 있 지 않 을 겁 니 다.3.2 잠 금 시효
잠 금 시 효 를 가 하 는 원 리 는 모든 방문 스 레 드 에 접근 시 효 를 증가 시 키 는 것 이다.만약 에 한 스 레 드 가 주어진 기한 내 에 필요 한 모든 자 물 쇠 를 성공 적 으로 얻 지 못 하면 이미 얻 은 자 물 쇠 를 되 돌려 주 고 풀 어 주 는 것 이다.
이 목 표를 실현 하기 위해 서 우 리 는 표 시 된 잠 금 을 사용 하지 않 고 신 호 량 Semaphore 로 제어 합 니 다.신 호 량 은 자원 이 얼마나 많은 스 레 드 에 접근 할 수 있 는 지 를 제어 할 수 있 습 니 다.여기 서 우 리 는 하나의 스 레 드 에 만 접근 할 수 있 고 비슷 한 잠 금 을 할 수 있 습 니 다.그리고 신 호 량 은 시간 초과 시간 을 지정 할 수 있 습 니 다.우 리 는 이 시간 초과 에 따라 추가 처 리 를 할 수 있 습 니 다.성공 적 으로 얻 을 수 없 는 경우 에는 반복 적 으로 시도 하거나 시도 횟수 를 지정 하거나 바로 종료 할 수 있 습 니 다.
package com.tl.skyLine.thread;
import java.util.Date;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* Created by tl on 17/3/3.
*/
public class UnDeadLock {
public static String bowl = " ";
//
public static final Semaphore a1 = new Semaphore(1);
public static String chopsticks = " ";
//
public static final Semaphore a2 = new Semaphore(1);
public static void main(String[] args) {
LockAa la = new LockAa();
new Thread(la).start();
LockBa lb = new LockBa();
new Thread(lb).start();
}
}
class LockAa implements Runnable {
public void run() {
try {
System.out.println(new Date().toString() + " ");
while (true) {
if (UnDeadLock.a1.tryAcquire(1, TimeUnit.SECONDS)) {
System.out.println(new Date().toString() + " ");
if (UnDeadLock.a2.tryAcquire(1, TimeUnit.SECONDS)) {
System.out.println(new Date().toString() + " , , ");
Thread.sleep(60 * 1000 * 10); // ,
} else {
System.out.println(new Date().toString() + " , ");
}
} else {
System.out.println(new Date().toString() + " , ");
}
UnDeadLock.a1.release(); //
UnDeadLock.a2.release();
System.out.println(new Date().toString() + " ");
Thread.sleep(1000); // , do something
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class LockBa implements Runnable {
public void run() {
try {
System.out.println(new Date().toString() + " ");
while (true) {
if (UnDeadLock.a2.tryAcquire(1, TimeUnit.SECONDS)) {
System.out.println(new Date().toString() + " ");
if (UnDeadLock.a1.tryAcquire(1, TimeUnit.SECONDS)) {
System.out.println(new Date().toString() + " , , ");
Thread.sleep(60 * 1000 * 10); // ,
} else {
System.out.println(new Date().toString() + " , ");
}
} else {
System.out.println(new Date().toString() + " , ");
}
UnDeadLock.a1.release(); //
UnDeadLock.a2.release();
System.out.println(new Date().toString() + " ");
Thread.sleep(10 * 1000);// , tryAcquire 1 , B A ,
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
결실
Fri Mar 03 18:12:07 CST 2017
Fri Mar 03 18:12:07 CST 2017
Fri Mar 03 18:12:07 CST 2017
Fri Mar 03 18:12:07 CST 2017
Fri Mar 03 18:12:08 CST 2017 ,
Fri Mar 03 18:12:08 CST 2017
Fri Mar 03 18:12:08 CST 2017 , ,
Fri Mar 03 18:12:10 CST 2017 ,
Fri Mar 03 18:12:10 CST 2017
Fri Mar 03 18:12:11 CST 2017
Fri Mar 03 18:12:11 CST 2017 , ,
분명히 볼 수 있 듯 이 우 리 는 자 물 쇠 를 만족 시 키 는 세 번 째 조 를 깨 뜨 렸 다.즉,자원 요구 자가 다른 자원 을 요구 하 는 동시에 기 존의 자원 에 대한 점 유 를 유지 하고 그릇 과 젓가락 을 완전히 빼 앗 지 못 했 을 때 두 사람(스 레 드)은 모두 차지 하 는 자원 을 방출 하여 자원 을 쟁탈 하기 시작 했다.이렇게 한 사람 이 그릇 과 젓가락 을 빼 앗 은 후에 배 불리 먹고 다른 사람 에 게 먹 인 다.이렇게 해서 당신 은 성공 적 으로 당신 의 두 동 료 를 구 했 습 니 다!Semaphore api:
acquire
public void acquire()
throws InterruptedException
, , 。 ( ) , 1。
, , :
release() , ;
。
:
on ;
。
InterruptedException, 。
:
InterruptedException -
release
public void release()
, 。 , 1。 , 。 ( ) 。
acquire() 。 。
wait()와 sleep()의 차이 점:sleep()방법 은 CPU 만 내 주 었 을 뿐 동기 자원 잠 금 을 풀 지 않 습 니 다!!
wait()방법 은 현재 스 레 드 가 동기 화 자원 자 물 쇠 를 잠시 양보 하여 이 자원 을 기다 리 고 있 는 다른 스 레 드 가 이 자원 을 얻 고 실 행 될 수 있 도록 하 는 것 을 말한다.
이상 의 자바 다 중 스 레 드 학습 의 잠 금 시 뮬 레이 션 과 피(인 스 턴 스 설명)는 바로 작은 편집 이 여러분 에 게 공유 하 는 모든 내용 입 니 다.여러분 께 참고 가 되 고 저희 도 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.