国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

java線程基礎

2019-11-06 08:16:14
字體:
來源:轉載
供稿:網友

 一、什么是線程 線程在某些場合可以當做輕量級進程來理解,是程序執行的最小單位(是系統調度和分派的基本單位),線程本身是由唯一id、當前指令針、寄存器集合、堆棧組成。線程是進程中的一個實體,線程本身除運行資源外,不擁有其他系統資源,但是可以與同一個進程組的其他線程共享資源,線程之間是相互制約的,呈現出間斷性。每一個程序都至少有一個線程,若程序只有一個線程,那就是程序本身。二、線程的狀態線程分為5個狀態1、新建:例如:new Thread();這個時候只是新創建了一個線程,線程本身還沒有任何代碼。2、就緒:創建線程后 執行了start()方法,會進行線程運行時需要的資源創建,資源創建完成后調用run()方法(這里只是調用 了 run,并沒有真正開始執行),當start()正確返回后,線程進入就緒狀態。注:調用了start()方法并不意味著線程會馬上執行,可能會由于cup時間片的競爭,或者當前線程需要其他線程占用的資源釋放后才能運行,這些情況的出現會延遲當前線程的開始執行時間3、運行:cup時間片和運行資源被當前線程搶到后 開始執行run()方法,只有開始執行run方法了線程才是運行狀態4、阻塞:簡單的來說就是線程由于某種原因暫時停止了繼續運行。阻塞只是讓出了cpu的時間片,并不是結束掉線程。    一般有以下情況會導致阻塞:(1)、調用了sleep()方法進行了睡眠。(2)在某個I/O操作上等待,比如網絡Socket中服務器監聽,或者鍵盤等待輸入,或者等待資源釋放等等情況。(3)線程想要得到一個鎖,但是資源被其他線程占用,必須等待被占用線程釋放資源。(4)線程等待條件觸發執行5、死亡:線程運行完成后自然進入死亡狀態,表示線程終結了,如果run()方法中有未捕獲的異常產生,會導致線程意外停止。死亡的線程是不能調用start()方法的,會拋出java.lang.IllegalThreadStateException異常三、如何創建一個線程1、繼承Thread類,實現 public void run(){}方法,這種方法的壞處是一旦A類繼承了Thread類,就不可以再被其他類繼承A的線程特性,線程方法必須是在A類中直接實現2、實現Runnable接口,需要實現run()方法,這種方式可以再去繼承其他對象。3、實現Callable接口  步驟:(1)創建Callable接口的實現類,并實現call()方法,該call()方法將作為線程執行體,并且有返回值。(2)創建Callable實現類的實例,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的返回值。(3)使用FutureTask對象作為Thread對象的target創建并啟動新線程代碼 ====================import java.util.concurrent.Callable;import java.util.concurrent.FutureTask;public class Ts implements Callable{@Overridepublic Object call() throws Exception {// TODO Auto-generated method stubreturn null;}public static void main(String[] args) {Ts t=new Ts();//由Callable創建一個FutureTask對象// FutureTask是一個包裝器,它通過接受Callable來創建,它同時實現了 Future和Runnable接口FutureTask task = new FutureTask(t); Thread thread = new Thread(task);thread.start();}} 四、如何結束一個線程一般線程如果沒有重復執行的可能性,那么走完run方法會自然結束掉,也有些其他場景是無限循環的,有3種方式結束線程:1、使用退出標志控制,在線程外部聲明一個布爾對象,線程內部用布爾值來控制線程代碼====================public volatile boolean exit = false; //使用volatile 修飾,保證當前對象同時只能有一個對象在修改    public void run()     {         while (!exit);     }     public static void main(String[] args) throws Exception     {         ThreadFlag thread = new ThreadFlag();         thread.start();         sleep(5000); // 主線程延遲5秒         thread.exit = true;  // 終止線程thread         thread.join();         System.out.PRintln("線程退出!");     } 2、使用stop方法,這種相當于立即強制性結束掉一個線程,會導致處理信息丟失等待問題,不到萬不得已,還是不要用這種方式。3、使用interrupt方法 (1)、在線程處于阻塞狀態時使用interrupt(),如果阻塞原因是調用了 sleep(),那么會拋出異常InterruptedException 代碼======================public class ThreadInterrupt extends Thread {     public void run()     {         try         {             sleep(50000);  // 延遲50秒         }         catch (InterruptedException e)         {             System.out.println(e.getMessage());         }     }     public static void main(String[] args) throws Exception     {         Thread thread = new ThreadInterrupt();         thread.start();         System.out.println("在50秒之內按任意鍵中斷線程!");         System.in.read();         thread.interrupt();         thread.join();         System.out.println("線程已經退出!");     } }  (2)、使用while(!isInterrupted()){}來判斷線程是否被中斷,如果返回false,就調用interrupt()方法,這樣的結果是,線程會找個機會自己退出來代碼================================public class ThreadA extends Thread {    private boolean isInterrupted=false;   int count=0;   public void interrupt(){       isInterrupted = true;       super.interrupt();      }      public void run(){       System.out.println(getName()+"將要運行...");       while(!isInterrupted){           System.out.println(getName()+"運行中"+count++);           try{               Thread.sleep(400);           }catch(InterruptedException e){               System.out.println(getName()+"從阻塞中退出...");               System.out.println("this.isInterrupted()="+this.isInterrupted());           }       }       System.out.println(getName()+"已經終止!");   }} ======關于線程中斷interupt()中斷線程一個線程從運行到真正的結束,應該有三個階段:正常運行.、處理結束前的工作,也就是準備結束.、結束退出.。

如何能確保線程真正停止?在線程同步的時候有一個叫“二次惰性檢測”(double check),能在提高效率的基礎上又確保線程真正中同步控制中。那么我把線程正確退出的方法稱為“雙重安全退出”,就是不以isInterrupted ()為循環條件 

五、線程常用的方法1、 sleep()這是一個靜態方法,只能控制當前正在運行的線程,sleep能保證線程最短不會運行時間,但是不能有效保證多少時間后能繼續運行,這與當前cup時間片與系統資源調度有關。2、getState()得到該線程的狀態3、isAlive()確定當前線程是否處在活動狀態。可運行或阻塞返回true,其他狀態返回false4、isInterrupted()判斷線程是否被中斷,已經中斷返回true,否則為false5、interrupt()中斷線程。一個線程強制停止是很危險的,這個方法并不會強制停止線程,而是告訴這個線程自己可以找個地方停下來了。如果無法中斷(例如進入一個同步鎖代碼塊時,是不能被中斷的),會拋出SecurityException,但是 ReentrantLock 支持可中斷的獲取模式即 tryLock(long time, TimeUnit unit)。6、getPriority()返回線程的優先級7、setPriority()更改線程的優先級8、join()等待線程終止,有參數可以設置等待該線程終止的時間最長為 millis 毫秒 + nanos 納秒。9、yield ()暫停當前正在執行的線程,并執行其他線程六、wait()與sleep()的區別sleep()可以將一個線程睡眠,參數可以指定一個時間。wait()可以將一個線程掛起,直到超時或者該線程被喚醒。(java.lang.Object類中提供了wait(), notify()和notifyAll()方法來操作線程)1、功能差不多,都用來進行線程控制,他們最大本質的區別是:sleep()不釋放同步鎖,wait()釋放同步鎖2、用法的上的不同是:sleep(milliseconds)可以用時間指定來使他自動醒過來,如果時間不到你只能調用interreput()來強行打斷;                             wait()可以用notify()直接喚起. sleep是Thread類的靜態方法。sleep的作用是讓線程休眠制定的時間,在時間到達時恢復,也就是說sleep將在接到時間到達事件事恢復線程執行,例如:try{System.out.println("I'm going to bed");Thread.sleep(1000);System.out.println("I wake up");}catch(IntrruptedException e) {} wait是Object的方法,也就是說可以對任意一個對象調用wait方法,調用wait方法將會將調用者的線程掛起,直到其他線程調用同一個對象的notify方法才會重新激活調用者,例如:try{obj.wait();}catch(InterrputedException e) {} 3、這兩者的施加者是有本質區別的  sleep()是讓某個線程暫停運行一段時間,其控制范圍是由當前線程決定,也就是說,在線程里面決定。  wait()是由某個確定的對象來調用的,將這個對象理解成一個傳話的人,當這個人在某個線程里面說"暫停!",也是obj.wait(),這里的暫停是阻塞 ,再等一個傳話人說“ok繼續執行”,就繼續起來執行兩者都可以讓線程暫停一段時間,但是本質的區別是一個線程的運行狀態控制,一個是線程之間的通訊的問題 總結sleep和wait的區別有:  1,這兩個方法來自不同的類分別是Thread和Object  2,最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。  3,wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在    任何地方使用   synchronized(x){      x.notify()     //或者wait()   }   4,sleep必須捕獲異常,而wait,notify和notifyAll不需要捕獲異常 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宁安市| 太仆寺旗| 海宁市| 北宁市| 白水县| 新龙县| 尤溪县| 墨江| 聂拉木县| 毕节市| 梨树县| 桐城市| 阳朔县| 武定县| 郯城县| 汕头市| 广丰县| 大新县| 鹰潭市| 斗六市| 高安市| 湟源县| 兰溪市| 双城市| 广德县| 五指山市| 澄江县| 迁西县| 平乡县| 和平区| 绍兴市| 紫云| 临城县| 横山县| 偃师市| 苍山县| 平江县| 禹州市| 新兴县| 田林县| 板桥市|