자바 스 레 드 조정 운행 사례 상세 설명

본 논문 의 사례 는 자바 스 레 드 의 조화 로 운 운행 조작 을 서술 하 였 다.여러분 께 참고 하도록 공유 하 겠 습 니 다.구체 적 으로 는 다음 과 같 습 니 다.
눈여겨보다
Object 류 가 제공 하 는 wait(),notify(),notify All()세 가지 방법 을 통 해 자바 스 레 드 의 조화 로 운 운행 을 실현 할 수 있 습 니 다.이 세 가지 방법 은 Thread 류 가 아니 라 Object 류 에 속한다.하지만 이 세 가지 방법 은 모니터 대상 을 동기 화해 야 한다.
이 세 가지 방법 에 대한 설명 은 다음 과 같다.
  • wait():다른 스 레 드 가 이 동기 모니터 의 notify()방법 이나 notify All()방법 으로 이 스 레 드 를 깨 울 때 까지 현재 스 레 드 를 기다 리 게 합 니 다.이 wait()방법 은 세 가지 형식 이 있 습 니 다.wait()방법 을 호출 하 는 현재 스 레 드 는 이 동기 모니터 에 대한 잠 금 을 해제 합 니 다.
  • notify():이 동기 모니터 에서 기다 리 는 단일 스 레 드 를 깨 웁 니 다.모든 스 레 드 가 이 동기 모니터 에서 기다 리 면 스 레 드 중 하 나 를 깨 우 는 것 을 선택 합 니 다.선택 은 임 의적 인 것 이다.현재 스 레 드 가 이 동기 모니터 에 대한 잠 금 을 포기 한 후(wait()방법 을 사용 해 야 깨 어 난 스 레 드 를 실행 할 수 있 습 니 다.
  • notify All():이 동기 모니터 에서 기다 리 는 모든 스 레 드 를 깨 웁 니 다.현재 스 레 드 가 이 동기 모니터 에 대한 잠 금 을 포기 해야만 깨 어 난 스 레 드 를 실행 할 수 있 습 니 다.
  • synchronized 수식 을 사용 하 는 동기 화 방법 에 대해 서 는 이러한 기본 인 스 턴 스(this)가 동기 화 모니터 이기 때문에 이 세 가지 방법 을 직접 호출 할 수 있 습 니 다.
    synchronized 수식 을 사용 하 는 동기 화 블록 에 대해 동기 화 모니터 는 synchronized 후 괄호 안의 대상 이기 때문에 이 대상 을 사용 하여 이 세 가지 방법 을 호출 해 야 합 니 다.
    실전
    1 Account 클래스
    
    public class Account
    {
       //       、           
       private String accountNo;
       private double balance;
       //               
       private boolean flag = false;
       public Account(){}
       //    
       public Account(String accountNo , double balance)
       {
          this.accountNo = accountNo;
          this.balance = balance;
       }
       // accountNo setter getter  
       public void setAccountNo(String accountNo)
       {
          this.accountNo = accountNo;
       }
       public String getAccountNo()
       {
          return this.accountNo;
       }
       //              ,    balance  getter  ,
       public double getBalance()
       {
          return this.balance;
       }
       public synchronized void draw(double drawAmount)
       {
          try
          {
            //   flag  ,             ,      
            if (!flag)
            {
               wait();
            }
            else
            {
               //     
               System.out.println(Thread.currentThread().getName()
                  + "   :" + drawAmount);
               balance -= drawAmount;
               System.out.println("     :" + balance);
               //                 false。
               flag = false;
               //       
               notifyAll();
            }
          }
          catch (InterruptedException ex)
          {
            ex.printStackTrace();
          }
       }
       public synchronized void deposit(double depositAmount)
       {
          try
          {
            //   flag  ,            ,       
            if (flag)       //①
            {
               wait();
            }
            else
            {
               //     
               System.out.println(Thread.currentThread().getName()
                  + "   :" + depositAmount);
               balance += depositAmount;
               System.out.println("     :" + balance);
               //                 true
               flag = true;
               //       
               notifyAll();
            }
          }
          catch (InterruptedException ex)
          {
            ex.printStackTrace();
          }
       }
       //         accountNo   hashCode() equals()  
       public int hashCode()
       {
          return accountNo.hashCode();
       }
       public boolean equals(Object obj)
       {
          if(this == obj)
            return true;
          if (obj !=null
            && obj.getClass() == Account.class)
          {
            Account target = (Account)obj;
            return target.getAccountNo().equals(accountNo);
          }
          return false;
       }
    }
    
    
    2 DrawThread 스 레 드 클래스
    
    public class DrawThread extends Thread
    {
       //       
       private Account account;
       //              
       private double drawAmount;
       public DrawThread(String name , Account account
          , double drawAmount)
       {
          super(name);
          this.account = account;
          this.drawAmount = drawAmount;
       }
       //   100       
       public void run()
       {
          for (int i = 0 ; i < 100 ; i++ )
          {
            account.draw(drawAmount);
          }
       }
    }
    
    
    3 DepositThread 스 레 드 클래스
    
    public class DepositThread extends Thread
    {
       //       
       private Account account;
       //               
       private double depositAmount;
       public DepositThread(String name , Account account
          , double depositAmount)
       {
          super(name);
          this.account = account;
          this.depositAmount = depositAmount;
       }
       //   100       
       public void run()
       {
          for (int i = 0 ; i < 100 ; i++ )
          {
            account.deposit(depositAmount);
          }
       }
    }
    
    
    4 테스트 클래스
    
    public class DrawTest
    {
       public static void main(String[] args)
       {
          //       
          Account acct = new Account("1234567" , 0);
          new DrawThread("   " , acct , 800).start();
          new DepositThread("    " , acct , 800).start();
          new DepositThread("    " , acct , 800).start();
          new DepositThread("    " , acct , 800).start();
       }
    }
    
    
    삼 운행 결과
    ......
    예금자 갑 예금:800.0
    계 정 잔액:800.0
    인출 자 인출:800.0
    계좌 잔액:0.0
    예금자
    계 정 잔액:800.0
    인출 자 인출:800.0
    계좌 잔액:0.0
    예금자 갑 예금:800.0
    계 정 잔액:800.0
    네 가지 설명
    이 절 차 를 실행 하면 예금자 의 스 레 드,인출 자 스 레 드 가 교체 되 어 집행 되 는 상황 을 볼 수 있 습 니 다.예금자 가 계좌 에 800 위안 을 입금 할 때마다 이 스 레 드 는 바로 계좌 에서 이 돈 을 찾 을 수 있 습 니 다.예금 이 완 료 된 후 계좌 잔액 은 항상 800 위안 이 고,인출 이 끝 난 후 계좌 잔액 은 항상 0 위안 이다.
    세 개의 예금자 스 레 드 는 무 작위 로 계좌 에 저금 하고 한 명의 돈 을 찾 는 사람 스 레 드 만 돈 을 찾 는 작업 을 한다.돈 을 찾 는 사람 이 돈 을 찾 아야 예금자 가 예금 할 수 있다.마찬가지 로 예금자 가 예금 을 한 후에 돈 을 찾 는 이 라인 만 돈 을 찾 을 수 있다.
    프로그램 이 마지막 에 막 혀 서 계속 아래로 실행 할 수 없 었 다.이것 은 3 개의 예금자 라인 이 모두 300 번 의 예금 조작 을 했 지만 1 개의 인출 자 라인 이 100 번 밖 에 조작 되 지 않 았 기 때문에 프로그램 이 마지막 에 막 혔 다.
    더 많은 자바 관련 내용 에 관심 이 있 는 독자 들 은 본 사이트 의 주 제 를 볼 수 있다.
    본 고 에서 말 한 것 이 여러분 의 자바 프로 그래 밍 에 도움 이 되 기 를 바 랍 니 다.

    좋은 웹페이지 즐겨찾기