자바 다 중 스 레 드 연습

8597 단어 #JavaSE
1. 스 레 드 동기 화 및 통신
      
허위 각성: increment 와 decrement 에 서 는 if 대신 while 를 사용 해 야 합 니 다. 기억 하 세 요: 다 중 스 레 드 에 서 는 if 를 사용 하지 않 고 while 를 사용 합 니 다. if 판단 이 이번에 통 과 될 수 있 지만 체 내 wait 를 기다 리 는 방법 도 있 기 때문에 while 를 사용 해 야 합 니 다.
class ShareData{
     private int number = 0;

     public synchronized void increment() throws InterruptedException{
           while(0 != number ){
               this.wait();
          }
          ++ number;
          System. out.println(Thread. currentThread().getName()+"\t"+ number);
           this.notifyAll();
     }

     public synchronized void decrement() throws InterruptedException{
           while(0 == number ){
               this.wait();
          }
          -- number;
          System. out.println(Thread. currentThread().getName()+"\t"+ number);
           this.notifyAll();
     }
}

/**
 *   :      ,         ,           1,         1,    , 10 ,       。
 * @author admin
 * 1            
 * 2                                
 */
public class ThreadDemo2{
     public static void main(String[] args){
           final ShareData shareData = new ShareData();

           new Thread(new Runnable(){
               @Override
               public void run()
              {
                    for (int i = 0; i < 10; i++){
                         try{
                             shareData.increment();
                             Thread. sleep(200);
                        } catch (InterruptedException e){
                             e.printStackTrace();
                        }
                   }
              }
          }, "AA").start();

           new Thread(new Runnable()
          {
               @Override
               public void run()
              {
                    for (int i = 0; i < 10; i++)
                   {
                         try
                        {
                             shareData.decrement();
                             Thread. sleep(300);
                        } catch (InterruptedException e){
                             e.printStackTrace();
                        }
                   }
              }
          }, "BB").start();

           new Thread(new Runnable()
          {
               @Override
               public void run()
              {
                    for (int i = 0; i < 10; i++)
                   {
                         try
                        {
                             shareData.increment();
                             Thread. sleep(400);
                        } catch (InterruptedException e){
                             e.printStackTrace();
                        }
                   }
              }
          }, "CC").start();

           new Thread(new Runnable()
          {
               @Override
               public void run()
              {
                    for (int i = 0; i < 10; i++)
                   {
                         try
                        {
                             shareData.decrement();
                             Thread. sleep(500);
                        } catch (InterruptedException e){
                             e.printStackTrace();
                        }
                   }
              }
          }, "DD").start();
     }
}

2. 동기 화 방법 추가, 정적 동기 화 방법 추가 연습
    //1 표준 접근, 애플 인지 안 드 로 이 드 인지 먼저 인쇄
    //2 Thread. sleep (4000) 을 넣 고 애플 을 먼저 인쇄 합 니까? 안 드 로 이 드 를 먼저 인쇄 합 니까?
    //3 getHello () 를 넣 고 사 과 를 먼저 인쇄 하 시 겠 습 니까? hello 를 먼저 인쇄 하 시 겠 습 니까?
    //4. 핸드폰 이 두 대 있 습 니 다. 애플 을 먼저 인쇄 하 시 겠 습 니까? 안 드 로 이 드 를 먼저 인쇄 하 시 겠 습 니까?
    //5. 정적 동기 화 방법 두 가지 가 있 습 니 다. 핸드폰 이 있 습 니 다. 애플 을 먼저 인쇄 하 시 겠 습 니까? 안 드 로 이 드 를 먼저 인쇄 하 시 겠 습 니까?
    //6. 두 개의 정적 동기 화 방법, 두 개의 핸드폰 이 있 습 니 다. 먼저 애플 을 인쇄 하 시 겠 습 니까? 안 드 로 이 드 를 인쇄 하 시 겠 습 니까?
    //7. 정적 동기 화 방법, 일반 동기 화 방법, 핸드폰 이 있 습 니 다. 애플 을 먼저 인쇄 하 시 겠 습 니까? 안 드 로 이 드 를 먼저 인쇄 하 시 겠 습 니까?
    //ios 를 먼저 인쇄 합 니 다. ios 에 서 는 클래스 개체 자체 가 잠 겨 있 기 때 문 입 니 다. 안 드 로 이 드 잠 금 은 인 스 턴 스 대상 자체 입 니 다.
    //8. 정적 동기 화 방법, 일반적인 동기 화 방법, 두 개의 핸드폰 이 있 습 니 다. 먼저 애플 을 인쇄 하 시 겠 습 니까? 안 드 로 이 드 를 인쇄 하 시 겠 습 니까?
public class ThreadDemo3{
    public static void main(String[] args){
          final Phone phone = new Phone();
          final Phone phone2 = new Phone();

          new Thread(new Runnable(){
              @Override
              public void run(){
                   for (int i = 0; i < 1; i++){
                        try{
                             phone.getIOS ();
                       } catch (InterruptedException e){
                            e.printStackTrace();
                       }
                  }
             }
         }, "AA").start();

          new Thread(new Runnable(){
              @Override
              public void run(){
                   for (int i = 0; i < 1; i++){
                        try
                       {
                             //phone.getAndroid();
                             //phone.getHello();
                            phone2.getAndroid();
                       } catch (InterruptedException e){
                            e.printStackTrace();
                       }
                  }
             }
         }, "BB").start();
    }
}

결론:
 
 
  
 한 대상 에 여러 개의 synchronized 방법 이 있 으 면 한 시간 동안 하나의 스 레 드 가 그 중의 synchronized 방법 을 호출 하면 다른 스 레 드 는 기다 릴 수 밖 에 없습니다. 다시 말 하면 특정한 시간 동안 유일한 스 레 드 만 이 synchronized 방법 에 접근 할 수 있 습 니 다.
     잠 긴 것 은 현재 대상 this 입 니 다. 잠 긴 후 다른 스 레 드 는 현재 대상 의 다른 synchronized 방법 에 들 어 갈 수 없습니다.
     일반적인 방법 을 추가 하면 동기 자물쇠 와 무관 합 니 다.
     두 대상 으로 바 뀌 면 같은 자물쇠 가 아니 라 상황 이 바로 달라 진다.
     모두 정적 동기 화 방법 으로 바 뀌 었 다가 상황 이 또 바 뀌 었 다.
     모든 비 정적 동기 화 방법 은 같은 자물쇠 - 인 스 턴 스 대상 자 체 를 사용 합 니 다. 즉, 인 스 턴 스 대상 의 비 정적 동기 화 방법 으로 자 물 쇠 를 가 져 오 면 이 인 스 턴 스 대상 의 다른 비 정적 동기 화 방법 은 자 물 쇠 를 가 져 오 는 방법 을 기 다 려 야 자 물 쇠 를 가 져 올 수 있 습 니 다.그러나 다른 인 스 턴 스 대상 의 비정 상 동기 화 방법 은 이 인 스 턴 스 대상 의 비정 상 동기 화 방법 과 다른 자 물 쇠 를 사용 하기 때문에 이 인 스 턴 스 대상 이 자 물 쇠 를 가 져 온 비정 상 동기 화 방법 을 기다 리 지 않 아 도 자 물 쇠 를 풀 수 있 습 니 다.
     모든 정적 동기 화 방법 은 같은 자물쇠 인 클래스 대상 자 체 를 사용 합 니 다. 이 두 자 물 쇠 는 서로 다른 대상 이기 때문에 정적 동기 화 방법 과 비 정적 동기 화 방법 사이 에는 경쟁 조건 이 없 을 것 입 니 다.그러나 정적 동기 화 방법 이 자 물 쇠 를 가 져 오 면 다른 정적 동기 화 방법 은 이 방법 이 자 물 쇠 를 풀 때 까지 기 다 려 야 자 물 쇠 를 가 져 올 수 있 습 니 다. 같은 인 스 턴 스 대상 의 정적 동기 화 방법 이 든 서로 다른 인 스 턴 스 대상 의 정적 동기 화 방법 이 든 같은 인 스 턴 스 대상 만 가 져 야 합 니 다!
3. 두 스 레 드 의 상호 교환 을 고찰 합 니 다. main 방법 에서 두 스 레 드 를 만 들 고 시작 합 니 다.첫 번 째 스 레 드 는 키보드 에서 'Q' 명령 을 읽 을 때 까지 100 이내 의 정 수 를 무 작위 로 인쇄 합 니 다.
class Phone{
    public static synchronized void getIOS() throws InterruptedException{
         Thread.sleep(4000);
         System.out.println("-----getIOS" );
    }

    public synchronized void getAndroid() throws InterruptedException{
         System.out.println("-----getAndroid" );
    }

    public void getHello() throws InterruptedException{
         System.out.println("-----getHello" );
    }
}
public class HelloThread4 implements Runnable{

     private static boolean flag = true;

     @Override
     public void run() {
         while(flag){
              int num = (int)(Math.random() * 101);
              System.out.println(num);
         }
     }

     public static void setFlag(){
         flag = false;
     }

}
public class HelloThread5 implements Runnable{
     @Override
     public void run() {
         Scanner scan = new Scanner(System.in);
         while(scan.hasNext()){
              String str = scan.next();
              if(str.equalsIgnoreCase("Q")){
                  HelloThread4.setFlag();
                   System.out.println("---------------------------------");
              }
         }
     }
}

4. 고찰 스 레 드 기본 사용: 프로그램 을 작성 하고 main 방법 에서 스 레 드 를 만 듭 니 다.스 레 드 는 일정 시간 (200 ms 이내 의 랜 덤 시간) 마다 0 - 100 사이 의 랜 덤 정 수 를 만 들 고 인쇄 한 후에 이 정 수 를 집합 에 넣 습 니 다.총 100 개의 정수 가 생 성 되 고 모두 생 성 된 후 30 초 동안 잠 을 자고 집합 내용 을 출력 합 니 다.main 스 레 드 에서 상기 수면 스 레 드 를 깨 워 집합 내용 을 빨리 인쇄 하도록 합 니 다.
/*
 *  main            。           100     ,             “Q”  。
 */
public class TestThread2 {

     public static void main(String[] args) {
         HelloThread4 ht4 = new HelloThread4();
         Thread t1 = new Thread(ht4);
         t1.start();

         HelloThread5 ht5 = new HelloThread5();
         Thread t2 = new Thread(ht5);
         t2.start();
     }

}

좋은 웹페이지 즐겨찾기