201871010116- 제나라 영국 레드 "객체 지향 프로그래밍 (자바)"주 17 학습 요약

텍스트 형식의 보웬의 시작 (2 점)

계획

함유량

"객체 지향 프로그래밍 (자바)"

https://home.cnblogs.com/u/nwnu-daizh/

어디에서 작업이 요구 사항

https://www.cnblogs.com/nwnu-daizh/p/12073034.html

작업 학습 목표

(1) 이해 속성 및 우선 순위 스케줄링 방법 스레드 마스터;

(2) 개념과 스레드 동기화 기술의 구현을 파악하는 단계;

(3) 자바는 포괄적 인 프로그래밍 연습 스레드

에세이 보웬의 본문 내용은 다음과 같습니다 :

첫 번째 부분 : 스레드 동기화 기술의 개요 (10 분)

스레드 동기화

멀티 스레드를 동시에 불확실성 솔루션을 실행 스레드 동기화 메커니즘의 도입을, 그래서 다른 스레드가이 방법을 사용하려면, 당신은 기다릴 수 있습니다.

 자바 솔루션 멀티 스레드 동기화, 두 가지가 있습니다 :

1 .- 자바 SE 5.0 ReentrantLock와 도입 클래스입니다.

2.- 동기화 개질제 공유 메모리 기반 방법 전에 첨가 하였다.

......

공공 정적 무효 동기화 부 (INT의 m)

......

해결 방법 1 : 잠금 개체 및 조건 객체

다음으로 상기 보호 ReentrantLock와 코드 블록의 기본 구조 :

() myLock.lock;

{시도

   임계 영역

} 드디어{

() myLock.unlock; }

잠금 개체 및 조건 개체에 대한 핵심 포인트 :

(1) 보호 된 임의의 시간에 하나의 스레드 만 코드를 실행하도록, 록 코드 세그먼트를 보호한다.

2 잠금 관리자 스레드는 보호 코드 세그먼트를 입력하도록 노력하고있다.

(3) 잠금 객체와 관련된 하나 개 이상의 조건을 가질 수있다.

4, 보호 된 코드 세그먼트를 입력했지만 실행할 수 없습니다 각 조건 개체 관리 스레드.

해결 방법 2 : 동기화 키워드

동기화 된 키워드의 역할 :

1 동기화 방법이라고 특정 클래스 동기화 변형 법 후;

2, 한 스레드가 동기화 방법에 액세스로, 다른 스레드 동기화 방법은 프리앰블 메소드가 리턴에서 스레드가 차단 된 스레드를 깨울 때까지, 다른 스레드의 당사자가 동기화 방법을 입력 할 수 있습니다 차단됩니다 액세스하려는.

스레드 동기화 방법을 사용하면 3, 그것은 필요에 문제가있을 수 있습니다,이 스레드가 일시적으로 대기 CPU를 사용할 수있는 권리를 포기하고, 다른 스레드가이 동기화 방법을 사용할 수 있도록하기 위해 대기 () 메서드를 사용해야합니다.

당신이 스레드 동기화 방법이 부족 4. 경우 때문에 말을 기다리는 대기 스레드에서이 방법의 사용에가는 notifyAll () 메소드의 통지 모든 동기화를 실행해야합니다.

개체 잠금

(1) 동기 처리 (고정 전류 객체)

(2) 코드의 동기화 블럭 (객체의 잠금)

동기 부호 블록이 고정 대상물을 설정하는 데 사용되어야한다면, 현재의 오브젝트를 잠글 일반적있다 :이.

(3) 동기 다 객체 잠금

객체가 복수의 동기 로크 조작 동기화 할 수없는 경우, 로크함으로써 얻어 질 수 록 같은 객체 잠금 키보다는 코드 조각 또는 방법 (함수)를 획득 동기화된다.

글로벌 잠금

글로벌 잠금을 달성하는 방법은 두 가지가 있습니다 :

(1) 정적 인 동기화 방법에 사용되는 키워드

동기화 정적 메소드는 정지형 클래스 잠겨 동기화 및 비 정적 방식은 오브젝트 잠금에인가되는인가. 클래스 잠금 장치는 모든 객체 클래스 인스턴스의 경우 기능 할 수있다.

(2) 클래스의 클래스와 동기화 객체를 잠급니다

정적 메소드 동기화 동일한 효과 코드 블록의 동기 (클래스) 연기.

멀티 스레드 액세스는 팔 방법을 동기화 :

A : 두 스레드가 동시에 개체의 동기화 방법에있어서, 동기 실행 액세스;

II는 두 스레드 병렬 동기화 방법 두 개체에 액세스;

방법 3 : 두 개의 스레드가 동시에 동기화 정적있어서, 동기 실행 액세스;

방법 4 : 두 개의 스레드가 동시에 액세스 동기화 및 비 동기화 방법에있어서, 동시 실행;

다섯 : 두 개의 다른 스레드가 동일한 객체, 동기 실행 액세스 동기화 방법;

여섯 두 스레드 동기화 방법 및 정적 비 정적 동기화 방법에있어서, 병렬 실행에 액세스;

세븐 : 방법은 잠금을 해제합니다, 예외를 던져;

여덟 : 일반적인 방법으로 전화 동기화 방법은 스레드로부터 안전하지 않습니다에서, 동기화 범위 만 역할을 "{}"내부;

파트 II : 실험 부분

실험 1 : 시험 절차 1 (5 분)

동기화 패키지 페널티에 대한; 

java.util의 클래스를 가져옵니다 * ;. 
가져 오기 java.util.concurrent.locks의 * ;. 

/ ** 
은행 계정 잠금 직렬화 액세스 @version를 사용하여, 많은 은행이 있습니다 1.30 2004년 8월 1일 * 
 * @author 케이 HORSTMANN 
 * / 
공용 클래스 은행 
{ 
   개인 파이널 더블 [] 계정, 
   개인 잠금 bankLock; 
   조건 조건 sufficientFunds에 대한 개인; 

   / ** 
    * 건설 은행. 
    파라미터 : N 계좌 
    * 각 계정 @param initialBalance 초기 밸런스 
    * / 
   공공 은행 (N-INT 더블 initialBalance)는 
   { 
      계정 새로운 새 = N-] 더블; 
      Arrays.fill (계정 initialBalance) 
      ReentrantLock와 새로운 새 =의 bankLock () ; 
      sufficientFunds을 bankLock.newCondition = ( ); // 대기 상태가되기 전에, 현재의 thread가 락을 보관해야합니다. 
   }

   / ** 
    * 하나 개의 계정에서 다른 돈. 
    파라미터 :는 계좌 이체에서 
    파라미터 :이 계정으로 전송되는 
    파라미터 : 내가 당신에게 전달 할 수 있도록 허용 
    * / 
   공공 무효 전송 (에 INT에서 INT, 더블 금액)가 발생 예외 : InterruptedException 
   { 
      bankLock.lock (); // 잠금 
      은 try 
      오브젝트 조건 {// 잠금 오브젝트 참조 
         그동안 (계정 [발] <AMOUNT) 
            // 인터럽트 신호를 수신하기 전에, 현재의 스레드를 초래하거나 대기 상태에있다가, sufficientFunds.await (). 
         ; System.out.print (는 Thread.currentThread ())를 
         - = AMOUNT 계정 []와 
         ; System.out.printf ( "% 10.2f % D의 D %의"AMOUNT로부터) 
         계정 [을] + = 양;
         System.out.printf ( "총 잔액 : % N- % 10.2f", getTotalBalance ()); 
         sufficientFunds.signalAll (); // 경우 상태로 대기 중의 모든 스레드, 모든 스레드까지 여파 
      } 
      최종적으로 
      { 
         bankLock.unlock (); // 잠금 해제. 
      } 
   } 

   / ** 
    * 모든 계정 잔액의 합계를 가져옵니다. 
    * @return 나머지 
    * / 
   공공 더블 getTotalBalance () 
   { 
      bankLock.lock (); 
      은 try 
      { 
         더블 SUM = 0; 

         (더블 A : 계정)에 대한 
            ; SUM = A + 

         리턴 SUM; 
      } 
      최종적으로 
      { 
         bankLock.unlock (); 
      }
   } 

   / **  
    * 은행에서 계정의 수를 가져옵니다. 
    * @return 계정
    * / 
   공공 INT 크기 () 
   { 
      반환 accounts.length; 
   } 
}

  

;에 대한 동기화 패키지 페널티 

/ ** 
 안전하게 다중 스레드 데이터 구조에 액세스하는 방법 *이 프로그램을 보여줍니다. 
 2015년 6월 21일 @version 1.31 * 
 * @author 케이 HORSTMANN 
 * / 
공용 클래스 SynchBankTest 
{ 
   NACCOUNTS 최종 = 100 INT 공용 static; 
   공공 정적 최종 더블 INITIAL_BALANCE = 1000; 
   공공 정적 최종 더블 MAX_AMOUNT = 1000; 
   딜레이 = INT 최종 공용 static 10; 
   
   공공 정적 무효 메인 (문자열 []에 args) 
   { 
      뱅크 뱅크 = 새로운 새 은행 (NACCOUNTS, INITIAL_BALANCE) 
      대 (INT I = 0; I <NACCOUNTS; I ++) 
      { 
         INT fromAccount = I, 
         실행 가능한 R & LT = () -> { 
            은 try 
            { 
               (참)을 동안
               { 
                  지능 toAccount = (INT) (bank.size () * 인 Math.random ()); 
                  더블 MAX_AMOUNT AMOUNT * = 인 Math.random (); 
                  bank.transfer (fromAccount, toAccount, AMOUNT) 
                  Thread.sleep를 ((INT) (DELAY * 인 Math.random ())) ; // 수면에 현재 실행중인 스레드에 지정된 밀리 초 확인 
               } 
            } 
            캐치 (예외 : InterruptedException E)을 
            { 
            }             
         } 
         스레드 스레드 새로운 새로운 T = (R LT) 
         t.start ( ); // 스레드가 실행을 시작 
      } 
   } 
}

  결과는 다음과 같습니다 :

잠금 개체 및 조건 개체에 대한 핵심 포인트 :

(1) 보호 된 임의의 시간에 하나의 스레드 만 코드를 실행하도록, 록 코드 세그먼트를 보호한다.

2 잠금 관리자 스레드는 보호 코드 세그먼트를 입력하도록 노력하고있다.

(3) 잠금 객체와 관련된 하나 개 이상의 조건을 가질 수있다.

4, 보호 된 코드 세그먼트를 입력했지만 실행할 수 없습니다 각 조건 개체 관리 스레드.

실험 예 1 : 시험 절차 2 (5 분)

;에 대한 synch2 패키지 페널티 

* ;. java.util에서 가져 오기 클래스 

/ ** 
 * 은행은 동기화 기본의 복수는 은행 계좌의 사용합니다. 
 2004년 8월 1일 @version 1.30 * 
 * @author 케이 HORSTMANN 
 * / 
공용 클래스 은행 
{ 
   개인 파이널 더블 [] 계정; 

   / ** 
    * 건설 은행. 
    파라미터 : N 계정 
    * 각 계정 @param initialBalance 초기 밸런스 
    * / 
   공공 은행 (N-INT는 더블 initialBalance)은 
   { 
      새로운 새로운 더블 = N-]는 계정; 
      Arrays.fill (계정 initialBalance) 
   } 

   / ** 
    * 하나 개의 계정에서 다른 돈. 
    * 계좌 이체에서 @Param 
    * @param 계정으로 전송되는 
    * 당신에 게 전달 할 수 있도록 허용 @param 
    * /
   동기화 무효 공중 이동 (에 INT에서 지능, 더블 금액은) 예외 : InterruptedException 던졌습니다 
   { 
      (<금액 [에서] 계정)을 잠시 
         대기 (); //이 중앙을 기다리는 스레드를 추가 
      System.out.print (는 Thread.currentThread () ) 
      계정 [발] - = AMOUNT; 
      System.out.printf ( "% 10.2f % D의 D %의"AMOUNT)로부터, 
      계정 [을] + = AMOUNT; 
      System.out.printf ( " 균형 총 다음 N- % 10.2f % ", getTotalBalance ()); 
      의 notifyAll ()는; // 현재 스레드가 차단 완화 
   } 

   / ** 
    * 모든 계정 잔액의 합계를 가져옵니다. 
    * @return 나머지 
    * / 
   공용 더블 getTotalBalance 동기화 () 
   { 
      더블 SUM = 0;

      (더블 A : 계정)에 대한 
         ; SUM = A + 

      리턴 SUM; 
   } 

   / ** 
    * 은행 계좌의 수를 가져옵니다. 
    @return * 
    * / 
   공용 INT 크기 () 
   { 
      복귀 accounts.length; 
   } 
}

  

synch2 패키지 페널티를 위해; 

/ ** 
 * 
 *이 프로그램은 데이터 구조에 대한 안전한 액세스를 위해 여러 스레드 동기화 방법을 사용하는 방법을 보여줍니다. 
 2015년 6월 21일 @version 1.31 * 
 * @author 케이 HORSTMANN 
 * / 
공용 클래스 SynchBankTest2 
{ 
   NACCOUNTS 최종 = 100 INT 공용 static; 
   공공 정적 최종 더블 INITIAL_BALANCE = 1000; 
   공공 정적 최종 더블 MAX_AMOUNT = 1000; 
   딜레이 = INT 최종 공용 static 10; 

   공공 정적 무효 메인 (문자열 []에 args) 
   { 
      뱅크 뱅크 = 새로운 새 은행 (NACCOUNTS, INITIAL_BALANCE가) 
      에 대해 INT (I = 0; I는 <NACCOUNTS는; I ++) 
      { 
         INT fromAccount = I는 // 내부 클래스가 사용 
         된 Runnable을 = R & LT () -> { 
            은 try
            { 
            	그동안 (true로) 
                { 
                   INT toAccount = (INT) (bank.size () *는 인 Math.random ()); // 밖의 임의의 계정 
                   이중 량 = MAX_AMOUNT * 인 Math.random () ; // 임의 설정 돈 
                   bank.transfer (fromAccount, toAccount, 양) ; // 전송 작업 
                   에 Thread.sleep ((INT) (DELAY * 인 Math.random ())); // 임의 수면 시간 
                } 
            } 
            캐치 (예외 : InterruptedException E) // 던져 이상 
            { 
            } 
         } 
         스레드 스레드 새로운 새로운 T = (R LT) 
         t.start () 
      } 
   } 
}

  결과는 다음과 같습니다 :

멀티 스레드 액세스는 팔 방법을 동기화 :

A : 두 스레드가 동시에 개체의 동기화 방법에있어서, 동기 실행 액세스;

II는 두 스레드 병렬 동기화 방법 두 개체에 액세스;

방법 3 : 두 개의 스레드가 동시에 동기화 정적있어서, 동기 실행 액세스;

방법 4 : 두 개의 스레드가 동시에 액세스 동기화 및 비 동기화 방법에있어서, 동시 실행;

다섯 : 두 개의 다른 스레드가 동일한 객체, 동기 실행 액세스 동기화 방법;

여섯 두 스레드 동기화 방법 및 정적 비 정적 동기화 방법에있어서, 병렬 실행에 액세스;

세븐 : 방법은 잠금을 해제합니다, 예외를 던져;

여덟 : 일반적인 방법으로 전화 동기화 방법은 스레드로부터 안전하지 않습니다에서, 동기화 범위 만 역할을 "{}"내부;

실험 예 1 : 시험 절차 3 (5 분)

클래스 Cbank 
{ 
     개인 정적의 INT의 = 2000; 
     공공 정적 공극 부 (INT의 m) 
     { 
           INT 임시 = S; 
           온도 - 온도 = m; 
          시도 { 
   			  Thread.sleep를 ((INT) (1000 * 인 Math.random ())); 
   			} 
           캐치 (의 InterruptedException e)는 {} 
    	      = s의 온도; 
    	      에서 System.out.println ( "S ="+는 S); 
  		} 
	} 


클래스 고객 나사 연장 
{ 
  ) 공공 무효 실행 ( 
  { 
   위한은 (INT 내가 = 1; I <= 4; I ++) 
     Cbank.sub (100); 
    } 
 } 
공용 클래스 Thread3 
{  
 공공 정적 무효 메인 (문자열 인수 [])
  { 
   고객 1 고객이) (새 고객을 =; 
   고객 customer2 새로운 고객을 () =; 
   customer1.start (); 
   customer2.start (); 
  } 
}  

결과는 다음과 같습니다 :

다음과 같이 개선 된 코드는 다음과 같습니다

클래스 Cbank 
{ 
     개인 정적의 INT의 = 2000; 
     공공 정적 무효 동기화 부 (INT의 m) 
     { 
           INT 온도 = S; 
           온도 - 온도 = m; 
          시도 { 
                 Thread.sleep를 ((INT) (1000 * 인 Math.random ())); 
               } 
           캐치 (의 InterruptedException e)는 {} 
              = s의 온도; 
              에서 System.out.println ( "S ="+는 S); 
          } 
    } 


클래스 고객 나사 연장 
{ 
  ) 공공 무효 실행 ( 
  { 
   위한은 (INT 내가 = 1; I <= 4; I ++) 
     Cbank.sub (100); 
    } 
 } 

공용 클래스 Thread3 
{
 공공 정적 무효 메인 (문자열 인수 []) 
  { 
   고객 = 1 고객 신규 고객 (); 
  
   고객 customer2 새로운 고객을 () =; 
   customer1.start (); 
   customer2.start (); 
  } 
}

  결과는 다음과 같습니다 :

이 실험 : 페어 프로그래밍 방법은 다음과 같은 네 부분을 커버 (10 분)

자매 결연 파트너 : 리 후아

프로그래밍 아이디어의 1) 설명;

    프로그램의 설계의 주요 아이디어는 너무 스레드 클래스와 오픈 스레드에서 쓰레드를 생성, 단지 세 개의 새로운 티켓 부스를 복잡하지 않고, 다음 스레드 작업에 정의 된 실행 방법, 예외 처리 디자인은 티켓 상황이 10 표 내에 게시 할 예정입니다 프로그램이 종료 된 10 개 이상의 표를 인쇄;

2) 프로그램 사양의 프로그램 코드와 라인;

package math;

public class Demo {
    public static void main(String[] args) {
        Mythread mythread = new Mythread();
        Thread ticket1 = new Thread(mythread);
        Thread ticket2 = new Thread(mythread);
        Thread ticket3 = new Thread(mythread);//新建三个Thread类对象
        ticket1.start();
        ticket2.start();
        ticket3.start();//调用thread类的start方法来开启线程
    }
}

class Mythread implements Runnable {//实现runnable接口进行线程的创建
    int ticket = 1;
    boolean flag = true;

    @Override
    public void run() {//将线程任务代码定义到run方法中
        while (flag) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            synchronized (this) {
                if (ticket <= 10) {
                    System.out.println(Thread.currentThread().getName() + "窗口售:第" + ticket + "张票");
                    ticket++;//票数在10张之内时,进行打印直到售出10张票时停止
                }
                if (ticket > 10) {
                    flag = false;
                }
            }
        }
    }

}

3)   程序运行功能界面截图;

 

实验总结:(5分)

在本周的学习中,我学习了线程同步这一知识点,我了解到这一知识点是用来解决多线程并发运行不确定性问题。学习了解决多线程同步问题的两种方案,分别是锁对象与条件对象引用和 synchronized关键字。在实验课上收获了当注释调代码sufficientFunds.await();会出现死锁状态等知识,感受颇多。注意点有:线程如果用完同步方法,应当执行notifyAll()方 法通知所有由于使用这个同步方法而处于等待的 线程结束等待。线程如果用完同步方法,应当执行notifyAll()方 法通知所有由于使用这个同步方法而处于等待的 线程结束等待。以后会坚持学习Java。

추천

출처www.cnblogs.com/qyhq/p/12078285.html