세 가지 자바 초보 입문 면접 문제,자유 로 운 길 로 가 는 다 중 스 레 드
스 레 드 안전 문제:일반적으로 다 중 스 레 드 모드 에서 여러 스 레 드 가 같은 공유 데 이 터 를 조작 할 때 첫 번 째 스 레 드 가 공유 데 이 터 를 업데이트 하지 못 해서 다른 스 레 드 가 최신 데 이 터 를 얻 지 못 하고 데 이 터 를 업데이트 하여 스 레 드 안전 문제 가 발생 하 는 것 을 말한다.비교적 흔히 볼 수 있 는 장면 은 표를 사 는 것 이다.
예 를 들 어 보 겠 습 니 다.
수요:예 를 들 어 주걸륜 콘서트 입장권 을 살 때 세 개의 창구 가 동시에 총 100 장의 표를 판다.창 은 스 레 드 대상 이 고 100 장의 표 자원 입 니 다.이 때 는 여러 스 레 드 가 cpu 의 자원 을 빼 앗 아 표 에 대한 사용권 을 빼 앗 는 것 과 같 습 니 다.
헤헤,대학 때 마 이 걸 이랑 보 러 간 거 야.이제 보 러 가 고 싶 어도 어 쩔 수 없어.말 이 많 지 않 으 니 코드 를 보 자.
public class SellTicketDemo {
public static void main(String[] args) {
//
Ticket ticket = new Ticket();
//
Thread thread = new Thread(ticket, " 1");
Thread thread2 = new Thread(ticket, " 2");
Thread thread3 = new Thread(ticket, " 3");
//
thread.start();
thread2.start();
thread3.start();
}
}
// Ticket Runnale
class Ticket implements Runnable {
private int ticket = 100; // 100
//
@Override
public void run() {
//
while (true) {
if (ticket > 0) { //
// : , ,
try {
// sleep , 。
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//
System.out.println(Thread.currentThread().getName() + " :" + ticket--);
}
}
}
}
여기 서 다음 과 같이 말 합 니 다.우 리 는 Ticket 이 Runnable 인 터 페 이 스 를 실현 하고 안의 run 방법 을 다시 써 서 표를 사 는 기능 을 실현 하 며 공 유 된 변 수 를 정의 합 니 다.그리고 main 방법 에서 세 개의 창 에서 표를 사 는 기능 을 실현 하기 위해 세 개의 스 레 드 를 만 들 었 습 니 다.마지막 으로 결 과 를 살 펴 보 자.당신 이 몇 번 더 운행 하면 이런 현상 을 볼 수 있 습 니 다.
전역 변수 와 정적 변수 로 인 한 것 입 니 다.모든 스 레 드 에서 전체 변수,정적 변 수 는 읽 기 동작 만 있 고 쓰기 동작 이 없 으 면 일반적으로 이 전체 변 수 는 스 레 드 가 안전 합 니 다.여러 개의 스 레 드 가 동시에 쓰기 작업 을 수행 하려 면 스 레 드 동기 화 를 고려 해 야 합 니 다.그렇지 않 으 면 스 레 드 안전 에 영향 을 줄 수 있 습 니 다.
스 레 드 안전 문제 가 발생 할 수 있 는 조건:
우 리 는 스 레 드 를 도입 하여 스 레 드 안전 문 제 를 동시에 해결 할 수 있다.위 에서 표를 파 는 문제 에서 다 중 스 레 드 가 한 자원 을 동시 방문 하 는 안전성 문제:즉,중복 표 와 표 가 존재 하지 않 는 문 제 를 해결 하 는 것 이다.자바 에서 동기 화 체제(
synchronized
)를 제공 하여 해결 했다.즉,구체 적 인 해결 방향 은 다음 과 같다.
1.창 1 스 레 드 가 티켓 팅 에 들 어 갈 때 창 2 와 창 3 스 레 드 는 밖에서 만 기다 릴 수 있 습 니 다.이 때 는 티켓 팅 작업 을 할 수 없습니다.창 1 티켓 팅 이 끝나 면 창 1 과 창 2,창 3 에 들 어가 cpu 의 자원 을 다시 선점 하여 티켓 팅 기능 을 수행 할 수 있 습 니 다.
2.즉,특정한 스 레 드 가 공유 자원 을 수정 할 때 다른 스 레 드 는 이 자원 을 수정 할 수 없습니다.수정 이 완 료 된 후에 야 CPU 자원 을 빼 앗 고 해당 하 는 작업 을 완성 하여 데이터 의 동기 성 을 확보 하고 스 레 드 가 안전 하지 않 은 현상 을 해결 할 수 있 습 니 다.
그리고
synchronized
키 워드 는 우리 에 게 몇 가지 방법 을 제공 합 니까?1.동기 코드 블록 실현:
synchronized
키 워드 는 방법 중의 한 블록 에 사용 할 수 있 고 이 블록 의 자원 에 만 상호 배척 방문 을 실시 하 는 것 을 나타 낸다.2.동기 화 방법 실현:
synchronized
수식 방법 을 사용 하 는 것 을 동기 화 방법 이 라 고 하 는데 한 스 레 드 가 이 방법 을 실행 하도록 보장 할 때 다른 스 레 드 는 방법 밖에서 만 기다 릴 수 있다.
public class SynchronizedDemo {
// this
private synchronized void synchronizedTest() {
}
// , , this, .class ,
private void synchronizedTest2(){
synchronized (this){
}
}
//
private synchronized static void synchronizedTest3() {
}
}
synchronized 키 워드 를 제외 하고 Lock 자물쇠 도 있 습 니 다.이 방법 은 자물쇠 의 방출 위 치 를 스스로 정의 해 야 합 니 다.
Lock lock = new ReentrantLock();
lock.lock(); //
try {
System. out. println(" ");
} catch (Exception e) {
} finally {
System. out. println(" ");
lock.unlock();// , 。
}
그럼 정리 해 보 겠 습 니 다.우 리 는 어떻게 안전 문 제 를 보증 합 니까?
1.synchronized 키 워드 를 사용 하여 동기 코드 블록 이나 동기 화 방법 을 실현 합 니 다.하나의 스 레 드 가 자원 에 대한 조작 을 보장 할 때 다른 스 레 드 는 기다 릴 수 밖 에 없다.
2.Lock 을 수 동 으로 잠 그 고 Lock 자 물 쇠 를 사용 하여 나타 나 는 위 치 는 상대 적 으로 유연 하지만 자 물 쇠 를 풀 어 주 는 동작 이 있어 야 합 니 다.
둘 의 차이:
잠 금 은 두 개 이상 의 프로 세 스(스 레 드)가 실행 과정 에서 경쟁 자원 이나 서로 통신 으로 인해 발생 하 는 차단 현상 을 말 하 는데 외력 작용 이 없 으 면 추진 할 수 없다.이 때 시스템 이 잠 금 상태 에 있 거나 시스템 에 잠 금 이 생 겼 다 고 합 니 다.서로 기다 리 고 있 는 프로 세 스(스 레 드)를 잠 금 프로 세 스(스 레 드)라 고 합 니 다.
예 를 들 어:너 는 네 여자 친구 와 싸 우기 시 작 했 어.너희들 은 서로 머리 를 꼬 집 기 시 작 했 어.너 는 그녀의 긴 머리 를 잡 고 있 었 고 그녀 는 너의 머리 를 잡 고 있 었 다.너희 둘 은 아 프 지 않 았 지만 서로 성질 이 급 했 어.서로 가 놓 아주 든 말 든 나 를 놓 아주 지 않 든 먼저 아파 죽 겠 어!이때 너 희 는 서 로 를 바라 보 며 손 을 놓 지 않 겠 다 고 소 리 쳤 다.지금 은 상당히 자물쇠 현상 이 생 겨 서로 기다 리 고 있다.
스 레 드 잠 금 코드 를 간단하게 보 여 드 리 겠 습 니 다.
public class DeadlockDemo {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
new Thread(myRunnable, " 1 ").start();
new Thread(myRunnable, " 2 ").start();
}
}
class MyRunnable implements Runnable {
Object me = new Object();
Object myGirl = new Object();
@Override
public void run() {
synchronized (me) {
System.out.println(Thread.currentThread().getName() + "me: ! ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "me: !");
synchronized (myGirl) {
System.out.println(Thread.currentThread().getName() + "me: ! ?");
}
}
synchronized (myGirl) {
System.out.println(Thread.currentThread().getName() + "myGirl: ! ? !");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "myGirl: !");
synchronized (me) {// t1 , objB, A ,
System.out.println(Thread.currentThread().getName() + "myGirl: ");
}
}
}
}
먼저 결 과 를 보다.먼저 우리 의 프로 세 스 가 실행 중인 상 태 를 볼 수 있 지만 코드 를 아래로 실행 하지 않 습 니 다.왜 일 까요?우 리 는 분석 해 보 겠 습 니 다.
이 상 태 는 스 레 드 1 이 두 번 째 synchronized(my Girl)라 는 동기 코드 블록 을 실행 하고 있 습 니 다.me 가 손 을 놓 기 를 기다 리 고 있 을 때 스 레 드 2 가 다시 들 어 왔 습 니 다.첫 번 째 synchronized(me)라 는 동기 코드 블록 을 실 행 했 습 니 다.me 를 잠 근 셈 입 니 다.
스 레 드 1 이때 두 번 째 synchronized(me)에 들 어 가 려 고 할 때 이 me 의 자 물 쇠 를 다른 사람 이 가 져 가면 대기 상태 에 빠 지고 스 레 드 2 는 첫 번 째 synchronized(my Girl)에 들 어가 야 한 다 는 것 을 알 게 되 었 고 my Girl 은 스 레 드 1 에 의 해 잡 혀 대기 상태 에 빠 졌 다.이때 상 태 는 두 사람 이 서로 가 자 물 쇠 를 풀 기 를 기다 리 며 무한 대기 상태 에 빠 진 것 이다.
자물쇠 가 생기 는 필수 조건 은 다음 과 같다.
두 개 또는 두 개 이상 의 스 레 드 는 실행 과정 에서 자원 쟁탈 로 인해 서로 기다 리 는 상 태 를 초래 했다.
이 글 은 여기까지 입 니 다.만약 이 글 이 당신 에 게 도 도움 이 된다 면,당신 이 우리 의 더 많은 내용 에 관심 을 가 져 주시 기 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.