세 가지 자바 초보 입문 면접 문제,자유 로 운 길 로 가 는 다 중 스 레 드

1.스 레 드 안전 문 제 를 아 십 니까?
스 레 드 안전 문제:일반적으로 다 중 스 레 드 모드 에서 여러 스 레 드 가 같은 공유 데 이 터 를 조작 할 때 첫 번 째 스 레 드 가 공유 데 이 터 를 업데이트 하지 못 해서 다른 스 레 드 가 최신 데 이 터 를 얻 지 못 하고 데 이 터 를 업데이트 하여 스 레 드 안전 문제 가 발생 하 는 것 을 말한다.비교적 흔히 볼 수 있 는 장면 은 표를 사 는 것 이다.
예 를 들 어 보 겠 습 니 다.
수요:예 를 들 어 주걸륜 콘서트 입장권 을 살 때 세 개의 창구 가 동시에 총 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 방법 에서 세 개의 창 에서 표를 사 는 기능 을 실현 하기 위해 세 개의 스 레 드 를 만 들 었 습 니 다.마지막 으로 결 과 를 살 펴 보 자.
당신 이 몇 번 더 운행 하면 이런 현상 을 볼 수 있 습 니 다.

  • 은 존재 하지 않 는 표를 팔 았 다.예 를 들 어 0 표 와-1 표 는 존재 하지 않 는 다.그리고 이런 일 은 허용 되 지 않 는 다.누가 0 장,심지어 1 장 을 팔 겠 는가.
  • 은 8 과 1 이라는 표 가 세 번 팔 렸 다.그럼 이 건 너무 하 네.표 한 장 에 세 명 더 팔 수 있어.하하.
  • 이 문제 들 의 발생 은 우리 가 방금 라인 이 안전 하지 않다 는 것 을 대표 한다.그 라인 안전 문 제 는 구체 적 으로 무엇 입 니까?우 리 는 총 결 할 수 있다.
    전역 변수 와 정적 변수 로 인 한 것 입 니 다.모든 스 레 드 에서 전체 변수,정적 변 수 는 읽 기 동작 만 있 고 쓰기 동작 이 없 으 면 일반적으로 이 전체 변 수 는 스 레 드 가 안전 합 니 다.여러 개의 스 레 드 가 동시에 쓰기 작업 을 수행 하려 면 스 레 드 동기 화 를 고려 해 야 합 니 다.그렇지 않 으 면 스 레 드 안전 에 영향 을 줄 수 있 습 니 다.
    스 레 드 안전 문제 가 발생 할 수 있 는 조건:
  • 다 중 스 레 드 환경 에서 단일 스 레 드 상황 에서 데이터 조작 을 하 는 지 여 부 는 당연히 문제 가 없 지!
  • 공유 변수 가 존재 하 는 지 여부 입 니 다.예 를 들 어 위의 코드 에서 전체 변수 ticket 의 콘서트 티켓 을 정 의 했 고 여러 스 레 드 에서 이 변 수 를 공유 합 니 다.
  • 에 여러 개의 문 구 를 조작 하여 데 이 터 를 공유 하 는 것 이 있 습 니까?예 를 들 어 위의 코드 에서 티켓 을 판매 한 후에 ticket 변 수 는 반드시 줄 여야 합 니 다.그래서 ticket 을 줄 이 는 작업 을 했 습 니 다.
  • 2.그러면 스 레 드 안전 문 제 를 어떻게 해결 합 니까?
    우 리 는 스 레 드 를 도입 하여 스 레 드 안전 문 제 를 동시에 해결 할 수 있다.위 에서 표를 파 는 문제 에서 다 중 스 레 드 가 한 자원 을 동시 방문 하 는 안전성 문제:즉,중복 표 와 표 가 존재 하지 않 는 문 제 를 해결 하 는 것 이다.자바 에서 동기 화 체제(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 자 물 쇠 를 사용 하여 나타 나 는 위 치 는 상대 적 으로 유연 하지만 자 물 쇠 를 풀 어 주 는 동작 이 있어 야 합 니 다.
    둘 의 차이:
  • synchronized 는 자바 의 키워드 이 고 Lock 은 하나의 클래스 입 니 다.인터페이스 입 니 다.보통 ReentrantLock 을 사용 하여 인 스 턴 스 대상 을 만 듭 니 다.synchronized 는 클래스,방법,변수 에 수식 할 수 있 고 동기 코드 블록 을 실현 할 수 있 으 며 ReentrantLock 은 코드 블록 잠 금 에 만 적 용 됩 니 다.
  • synchronized 는 대상 머리 에 mark word 를 작 동 하 는 것 이 고 ReentrantLock 바 텀 은 Unsafe 의 Park 방법 으로 자 물 쇠 를 채 우 는 것 입 니 다.
  • ReentrantLock 은 수 동 으로 자 물 쇠 를 가 져 오고 풀 어야 하 며,synchronized 는 수 동 으로 자 물 쇠 를 풀 거나 열 필요 가 없습니다.
  • 둘 다 잠 금 을 다시 넣 을 수 있 습 니 다.잠 금 을 다시 넣 을 수 있 는 것 은 같은 스 레 드 가 같은 자 물 쇠 를 여러 번 가 져 올 수 있 도록 하 는 것 입 니 다.만약 에 특정한 스 레 드 가 특정한 자 물 쇠 를 얻 었 다 면 자 물 쇠 를 다시 가 져 올 수 있 습 니 다.잠 그 지 않 고 다시 들 어가 면 잠 금 이 생 긴 다.
  • 3.그럼 자물쇠 가 뭔 지 말씀 해 주 시 겠 어 요?
    잠 금 은 두 개 이상 의 프로 세 스(스 레 드)가 실행 과정 에서 경쟁 자원 이나 서로 통신 으로 인해 발생 하 는 차단 현상 을 말 하 는데 외력 작용 이 없 으 면 추진 할 수 없다.이 때 시스템 이 잠 금 상태 에 있 거나 시스템 에 잠 금 이 생 겼 다 고 합 니 다.서로 기다 리 고 있 는 프로 세 스(스 레 드)를 잠 금 프로 세 스(스 레 드)라 고 합 니 다.
    예 를 들 어:너 는 네 여자 친구 와 싸 우기 시 작 했 어.너희들 은 서로 머리 를 꼬 집 기 시 작 했 어.너 는 그녀의 긴 머리 를 잡 고 있 었 고 그녀 는 너의 머리 를 잡 고 있 었 다.너희 둘 은 아 프 지 않 았 지만 서로 성질 이 급 했 어.서로 가 놓 아주 든 말 든 나 를 놓 아주 지 않 든 먼저 아파 죽 겠 어!이때 너 희 는 서 로 를 바라 보 며 손 을 놓 지 않 겠 다 고 소 리 쳤 다.지금 은 상당히 자물쇠 현상 이 생 겨 서로 기다 리 고 있다.
    스 레 드 잠 금 코드 를 간단하게 보 여 드 리 겠 습 니 다.
    
    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 에 의 해 잡 혀 대기 상태 에 빠 졌 다.이때 상 태 는 두 사람 이 서로 가 자 물 쇠 를 풀 기 를 기다 리 며 무한 대기 상태 에 빠 진 것 이다.
    자물쇠 가 생기 는 필수 조건 은 다음 과 같다.
    두 개 또는 두 개 이상 의 스 레 드 는 실행 과정 에서 자원 쟁탈 로 인해 서로 기다 리 는 상 태 를 초래 했다.
  • 상호 배척 조건:스 레 드 는 분 배 된 자원 에 대해 배타 적 입 니 다.즉,하나의 자원 은 하나의 스 레 드 에 만 점용 되 고 이 스 레 드(프로 세 스)에 의 해 방출 될 때 까지 만 사용 할 수 있 습 니 다.
  • 요청 과 유지 조건:하나의 스 레 드 가 자원 점용 요청 으로 인해 차단 되 었 을 때 이미 얻 은 자원 을 놓 지 않 습 니 다.즉,하나의 스 레 드 는 이미 자원 의 자격 이 있 는 후에 새로운 자원 요 구 를 제 기 했 습 니 다.
  • 박탈 하지 않 는 조건:스 레 드 에서 얻 은 자원 은 마지막 에 사용 하기 전에 다른 스 레 드 에 의 해 강제로 박탈 당 할 수 없고 자신 이 사용 한 후에 야 자원 을 방출 합 니 다.
  • 순환 대기 조건:잠 금 이 발생 할 때 기다 리 는 스 레 드 는 반드시 자원 의 링 체인(죽은 순환 과 유사)을 형성 하여 영구적 으로 막 힐 것 이다.
  • 총결산
    이 글 은 여기까지 입 니 다.만약 이 글 이 당신 에 게 도 도움 이 된다 면,당신 이 우리 의 더 많은 내용 에 관심 을 가 져 주시 기 바 랍 니 다!

    좋은 웹페이지 즐겨찾기