黑馬程序員-(多線程)瞭解線程與如何解決線程同步到來的安全問題!(面試)

------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a>、期待與您交流! ----------

線程總結:

     創建線程的兩種方式:
       1.繼承Thread類,重寫Thread的run方法,因爲Thread類的run方法沒有內容,創建繼承Thread的子類調用start方法來啓動線程
       2.實現Runnable接口,實現接口中的run方法,實現Runnable接口的類作爲參數,創建Thread對象,對象調用start方法來啓動線程
       
     線程的生命週期:
       1.新建
       2.運行
線程創建後僅僅佔用內存資源,還必須調用start方法才能啓動該線程。
在線程沒有結束run方法之前,不要讓線程在調用start方法,否則會發生IllegalThreadStateException異常


       3.中斷
1.JVM將線程切換給其他線程
2.線程在使用CPU期間執行了sleep方法
3.線程在使用CPU期間執行了wait方法
4.線程執行期間某項操作進入阻塞狀態
阻塞的三種情況:
4.1調用了sleep方法
4.1調用了join方法:處在執行狀態的線程調用了其他線程的join方法,該線程將被掛起進入“阻塞狀態”
目標線程完成後纔會解除阻塞狀態,回到執行狀態。
4.3執行了I/O操作:
  線程在執行過程中如果因爲訪問外部資源(等待用戶鍵盤輸入、訪問網絡)
  時發生了阻塞,也會導致當前線程進入“阻塞狀態”。


       4.死亡   

1.線程執行完畢,結束run方法

2.強制結束run方法

join方法在線程中的使用:

/**
 * 需求: 測試join方法在線程中的使用
 * 分析:通過在主線程中創join新線程,查看運行結果
 * 代碼實現:
 * @author Administrator
 *
 */
public class JionThreadTest extends Thread {
	private int no;//線程編號
	public JionThreadTest(int no){//帶參構造
		this.no=no;
	}
	
	//重寫父線程的run方法
	@Override
	public void run() {
		//打印50遍 線程編號
		for(int i=0;i<=50;i++){
			System.out.println(no);
		}
	}
	
	public static void main(String[] args) {
		//創建線程對象
		JionThreadTest threadTest=new JionThreadTest(1);
		//開始線程
		threadTest.start();
		
		try {
			//調用join 方法掛起主線程
			threadTest.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		for(int i=0;i<=50;i++){
			System.out.println("這是主線程。。。");
		}
		System.out.println("線程執行結束。。。");
	}
}
當一個線程阻塞的情況下,可以通過調用線程的interrupt方法往下執行:

/*
 * 需求:當一個線程阻塞的情況下,可以通過調用線程的interrupt方法往下執行
 * 分析:讓某個線程睡1萬毫秒,模擬進入阻塞狀態,調用interrupt方法繼續往下執行。
 * 代碼實現 :
 */
public class InterruptThreadTest extends Thread {
@Override
public void run() {
		try {
			sleep(1000000000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//睡眠一段時間後輸出5個數字
		for(int i=0;i<5;i++){
			System.out.println(i);
		}
}
public static void main(String[] args) {
	InterruptThreadTest thread=new InterruptThreadTest();
	thread.start();
	//調用睡眠線程的Interrupt方法
	thread.interrupt();
}
}
線程優先級:

線程的優先級:Priorty  線程設置了10個優先級別,數值越高優先級越高(在實際的應用中不建議使用)

線程同步:

/*
		 *需求: 問題:通過多線程解決小朋友分蘋果的問題:一共有5個蘋果,
		 *		2個小朋友同時拿蘋果,每次拿一個,拿完爲止
		 *分析:兩個小朋友兩條線程,兩個小朋友一起拿五個蘋果,兩條線程共同搶佔一個內存空間
		 *
		 *代碼實現:
		 *
		 *結論:如果按照以上方法實行,線程或出現阻塞或者佔用的情況,解決方法:線程同步synchronized
		 *	在getApple方法之前加synchronized關鍵字
		 */
		public class ShareApple implements Runnable {
			//蘋果總數
			private int  appleCount=5;
			//線程是否執行
			private boolean isRun=true;
			//拿走蘋果
			public boolean getApple(){
				if(appleCount==0){
					return false;
				}
				appleCount--;//蘋果數量減1
				
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				if(appleCount>=0){
					System.out.println(Thread.currentThread().getName()+
							"小朋友拿走了一個蘋果,還剩下"+appleCount+"個蘋果!");
				}else{
					System.out.println(Thread.currentThread().getName()+"發現蘋果沒了");
				}
				return true;
				
			}
			public void run() {
				while(isRun){
					isRun=getApple();
				}
				if(appleCount<=0){
					System.out.println(Thread.currentThread().getName()+"線程進入死亡狀態");
					return;
				}
			}
			
			public static void main(String[] args) {
				ShareApple shareApple=new ShareApple();
				Thread child1=new Thread(shareApple);
				child1.setName("小明");
				Thread child2=new Thread(shareApple);
				child2.setName("小強");
				child1.start();
				child2.start();
				
			}

		}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章