多線程

java中的多線程是一個同時執行多個線程的進程,線程是一個輕量級的子進程,是最小的處理單位。線程是進程的一條執行路徑,

而進程是線程的集合。

1.優點:

         ① 他不會阻塞用戶,因爲線程是獨立的,可以同時執行多個操作。

         ② 可以一起執行許多操作,因此可以節省時間。(提高程序效率)

         ③ 線程是獨立的,因此如果單個線程中發生異常,他不會影響其他線程。

 

2.多任務處理

         多任務處理是同時執行多個任務的過程。使用多任務來利用CPU,多任務處理可以通過兩種方式來實現:

         ① 基於進程的多任務處理(多進程)

              特點:每個進程在內存中都單獨分配有一個內存區域,進程是重量級的。進程之間的通信成本很高。從

                        一個進程切換到另一個進程需要一些時間來保存和加載寄存器、內存映射、更新列表等。

         ② 基於線程的多任務處理 (多線程)

              特點:線程共享相同的地址空間;線程之間是輕量級的;線程之間的通信成本很低。

3.Thread類

   java提供了Thread類來實現線程編程。Thread類提供了在線程上創建和執行操作的構造函數和方法。Thread類

   擴展了object類並實現了runnable接口。

   創建線程的方式: MyThread myThread = new MyThread();

4.runnable接口

   創建線程有兩種方式,一種是直接繼承Thread類,另外一種是實現runnable接口。相比較Thread而言,通過實現

   runnable的方式可以更容易地實現資源共享,並且接口可以多實現且還能再繼承其他類。

  總結:① 適合多個相同的程序代碼的線程去處理同一個資源

             ② 可以java中單繼承的限制

             ③ 增加程序的健壯性,代碼可以被多個線程共享,代碼和數據獨立。

  創建線程的方式: MyThread myThread = new MyThread();     //只需要創建一個實例化對象然後被多個線程使用

                               Thread Thread1 = new Thread(myThread);  //線程1

                               Thread Thread2 = new Thread(myThread);  //線程2

 

  5.線程生命週期

            ① 新建狀態:通過new創建一個線程,跟其他對象的創建時一樣的。此時虛擬機會爲其分配內存,並初始化

                                   其成員變量的值。

            ② 就緒狀態:當線程對象調用了start方法之後,線程就進入了就緒狀態。程序就會爲其創建方法調用棧和程

                                   序計數器,處於這個狀態中的線程並沒有開始運行,只是表示該線程可以運行了,至於何時運

                                   行,取決於jvm中的線程調度器的調度。

            ③ 運行狀態:當處於就緒狀態的線程獲得cpu,開始執行run()方法的線程執行體時,線程就進入了運行狀態,

                                   線程調度的細節取決於底層平臺採用的策略(搶佔式調度策略和協作式調度策略)

            ④ 阻塞狀態:運行狀態的線程遇到以下情況就會進入阻塞狀態:

                                  1.線程自己調用sleep方法主動放棄處理器資源;

                                  2.該線程調用了一個阻塞式IO方法,在該方法返回之前,該線程處於阻塞狀態。

                                  3.該線程試圖獲得一個同步監視器,但該同步監視器正被其他線程持有。

                                  4.線程正在等待某個通知(notify)

                                  5.程序調用了線程的suspend方法,將線程掛起(容易導致死鎖,避免使用)

           ⑤ 死亡狀態:有三種情況會使線程進入死亡狀態:

                                  1.run方法執行完成,線程正常結束。

                                  2.線程拋出未被捕獲的exception或者error

                                  3.人爲停止,比如調用stop方法(暴力停止,不建議使用),以及其他停止策略。

       

   6.線程中常用的方法

                          

package com.multithreading.test;

//創建線程類,方法一
public class MyThread extends Thread {
	public MyThread() {
		
	}
	public MyThread(String threadName,ThreadGroup tg) {
		super(tg,threadName);
		start();
	}
	//線程功能函數
	public void run() {
		for(int i=1;i<=5;i++) {
			try {
				Thread.sleep(500);
			} catch (Exception e) {
				System.out.println(e.toString());
			}
				System.out.println(Thread.currentThread().getName()+":"+i);
			
		}
		
	}
	
	
    public static void main(String[] args) throws InterruptedException {
    	
    	//創建線程的方式1
    	MyThread myThread = new MyThread();
    	myThread.start();
    	myThread.interruptAndIsInterruptedAndInterrupted();
    	
    	
    	
    	//創建線程的方式2
    	MyThread3 MyThread3 = new MyThread3();
    	
    	//線程1
    	Thread t1 = new Thread(MyThread3);
    		   t1.start();
        //線程2
        Thread t2 = new Thread(MyThread3);
    		   t2.start();
        
 
    	
    	
	}
    
   	//1. start()  啓動線程  線程方法
    public static void starts() {
    	MyThread myThread= new MyThread();
    	myThread.start();
    	
    }
    //2. run()  執行線程  線程方法
    public static void runs() {
    	
    	//開啓線程之後,會自動運行run方法執行線程代碼功能。如上上
    	MyThread myThread= new MyThread();
    	myThread.start();
    	
    }
    
    //3. sleep() 指定的時間內休眠線程
    public static void sleep() throws InterruptedException {
    	MyThread myThread= new MyThread();
    	myThread.start();
    	myThread.sleep(1000);   //休眠一秒鐘(多線程中不會釋放對象鎖,與wait的比較)
    	
    }
    //currentThread()    返回對當前正在執行線程對象的引用   線程方法
    public static void currentThreads() {
    	MyThread myThread= new MyThread();
    	myThread.setName("我是MyThread");
    	myThread.start();
    	Thread t = Thread.currentThread();   //主線程
    	System.out.println(myThread.getName());
    	
    }
    //join()    實現線程的執行順序  線程方法
    public static void joins() {
    	MyThread myThread1= new MyThread();
    	myThread1.setName("myThread1");
    	MyThread myThread2= new MyThread();
    	myThread2.setName("myThread2");
    	MyThread myThread3= new MyThread();
    	myThread3.setName("myThread3");
    	
    	myThread1.start();
    	try {
			myThread1.join(1500);   //myThread1優先執行1500毫秒
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	myThread2.start();
    	myThread3.start();
    	
    }
    
    //setpriority()  設置線程優先級(1-10,默認爲5,數字越大優先級越高,但不代表級別越高就一定優先執行,只是優先執行的概率更大)  
    //getPriority()  返回線程優先級級別
    //另外還有三個常規優先級屬性   MIN_PRIORITY設置最小優先級,值爲1     MAX_PRIORITY設置最大優先級,值爲10   NORM_PRIORITY普通優先級值爲5   
    public static void setPriorityAndGetPriority() {
    	MyThread myThread1= new MyThread();
    	MyThread myThread2= new MyThread();
    	
    	myThread1.setPriority(1);
    	myThread1.setName("myThread1");
    	System.out.println(myThread1.getPriority());
    	
    	myThread2.setPriority(9);
    	myThread2.setName("myThread2");
    	System.out.println(myThread2.getPriority());
    	
    	myThread1.start();
    	myThread2.start();
    	
    	//myThread1.setPriority(Thread.MIN_PRIORITY);
    	//myThread1.setPriority(Thread.MAX_PRIORITY);
    	//myThread1.setPriority(Thread.NORM_PRIORITY);
    	
    }
    
    //setName() 設置線程名稱
    //getName() 獲取線程名稱
    public static void setNameAndGetName() {
    	//以上方法中已經多次應用
    }

    //返回線程編號
    public static void geId() {
    	MyThread myThread= new MyThread();
    	myThread.getId();
    	System.out.println(myThread.getId());
    }
    
    
    //isAlive()  測試線程是否活着  線程方法
    public static void isAlives() {
    	MyThread myThread= new MyThread();
    	myThread.start();
    	System.out.println(myThread.isAlive());  
    }
    
    //yield()      Thread類的yield()方法導致當前正在執行的線程對象暫停並允許其他線程執行(其實就是降低優先級,但不代表不會先執行)
    public static void yield() {
    	MyThread myThread1= new MyThread();
    	myThread1.setName("myThread1");
    	MyThread myThread2= new MyThread();
    	myThread2.setName("myThread2");
    	myThread1.start();
    	myThread2.start();
    	
    	for(int i=0;i<3;i++) {
    		//如果myThread1線程正在執行,則執行該方法,意味着自己不運行run,重新回到就緒狀態與其他線程一同競爭cpu時間
    		myThread1.yield();
    		System.out.println(myThread1.getName()+":我們一同競爭吧");
    	}
         
    }
    
    //stop()   暴力停止線程,強制中斷線程的執行。容易造成數據不一致,屬於不安全的方法,包括suspend()(阻塞線程)  resume()(恢復線程) 等已經棄用
    public static void  stops() {
    	
    	//略
    	
    	
    }
    //destroy()    銷燬線程組以及子線程組
    //ThreadGroup  線程組類,管理線程的類,即線程組就是由線程組成的管理線程的類,這個類是java.lang.ThreadGroup類
    public static void destroys() throws InterruptedException {
    	//創建一個名爲Parent thread的線程組
    	ThreadGroup g1 = new ThreadGroup("Parent thread");  
    	
    	//創建一個名爲Child thread的線程組
    	ThreadGroup g2 = new ThreadGroup("Child thread");  
    	
    	//在線程組中創建線程,在有參構造函數已經啓動了線程
    	MyThread myThread1= new MyThread("myThread1",g1);
    	MyThread myThread2= new MyThread("myThread2",g2);
    	
    	
    	myThread1.join();
    	myThread2.join();
    	
    	g1.destroy();
    	System.out.println(g1.getName()+" is destoried");
    	
    	g2.destroy();
    	System.out.println(g2.getName()+" is destoried");
    }
    
    // 	isDaemon()  該線程是否是一個守護線程
    //  setDaemon() 將線程標記爲守護線程或用戶線程
    public static void  isDaemons() {
       	MyThread myThread= new MyThread();
    	
       	System.out.println(myThread.isDaemon());
       	
       	myThread.setDaemon(true);
       	
       	System.out.println(myThread.isDaemon());
       	//守護線程與用戶線程(非守護線程)
       	//守護線程是爲用戶線程服務的,比如垃圾回收線程,非必要線程。當所有的非守護線程結束時,程序也就終止了,同時會殺死進程中的所有守護線程
       	//用戶線程就是執行業務功能代碼的線程。
       	
       	
    }
    
    //interrupt()      標記需要中斷的線程,中斷的執行由具體實現代碼決定
    //isInterrupted()  用來判斷當前線程的中斷狀態
    //interrupted()    此方法清除線程的中斷狀態,這意味着如果要連續兩次調用此方法,則第二次調用將返回false。 如果線程的中斷狀態爲true,則此方法將狀態設置爲false
    public  void interruptAndIsInterruptedAndInterrupted() {
    	MyThread2 myThread= new MyThread2();
      	
      	myThread.start();
      	
      	System.out.println(myThread.isAlive());
      	
      	myThread.interrupt();
    	System.out.println(myThread.isAlive());	
      	
    }
   
    
    class MyThread2 extends Thread{
    		
    	public void run() {
    		for(int i=1;i<=5;i++) {
    			try {
    				//爲true時,說明被標記爲需要中斷的線程,然後通過return直接返回來實現中斷線程
    			     if(Thread.currentThread().isInterrupted()) {
    			    	 return;
    			     }
    			} catch (Exception e) {
    				System.out.println(e.toString());
    			}
    				System.out.println(Thread.currentThread().getName()+":"+i);
    			
    		}
    		
    	}
    }
    
    
    //notify()    隨機喚醒wait等待池中的線程,從而可以去競爭獲取對象鎖
    //notifyAll()  喚醒所有wait等待池中的線程
    public  static void notifyAndNotifyAll() {
    	
    	//略
    	
    }
    //wait  使線程進行阻塞狀態,並且會釋放鎖
    public  static void waits() {
    	
    	//略
    	
    }
    
}


//創建線程方法2,實現rnnable接口
class MyThread3 implements Runnable{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		
	}
	
}

       

 

 

 

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