多執行緒1
阿新 • • 發佈:2018-12-17
//程式就是[可執行]的檔案 //程式執行起來就是一個程序 //執行緒是程序的最基本單位 //只要有程序,就最少有一個執行緒 //CPU線上程上幹活 /* * 多執行緒: * * 程式:是一個可執行的檔案. * 程序:是一個正在執行的程式.在記憶體中開闢了一塊兒空間 * 執行緒:負責程式的執行,可以看做程式執行的一條通道或者一個執行單元.所以我們通常將程序的工作理解成執行緒的工作. * * 程序中可不可以沒有執行緒? 必須有執行緒,至少有一個,當有一個執行緒存在的時候,我們稱為單執行緒,這個唯一的執行緒就是主執行緒(main執行緒) * 當有兩個及講個個以上的執行緒存在的時候,我們稱為多執行緒. * * 多執行緒存在的意義:為了實現同一時間做多件事情. * * 任務區:我們將執行緒完成工作的方法稱為任務區。其實任務區就是run()方法 * 每一個執行緒都有自己的任務區 * * JVM是多執行緒嗎? * 一定是多執行緒 * 至少有兩個 * 主執行緒的任務區:main方法 * 垃圾回收執行緒的任務區:finalize()方法 */ public class Demo7 { public static void main(String[] args)//--有一個執行緒:主執行緒 { new MyTest();//匿名物件---垃圾 /* * 手動執行gc:垃圾回收器,執行垃圾回收機制。 * * 原理:當執行gc方法時,會觸發垃圾回收機制,開啟垃圾回收執行緒,自動呼叫finalize方法 */ //注意點:多個執行緒之間是搶cpu的關係,cpu有隨機性 System.gc();//有兩個執行緒 System.out.println("main"); }//主函式結束,主任務區結束,執行緒隨著任務的結束而結束,隨著任務的開始而開始, //main()相當於開啟主執行緒,並執行裡面的程式(任務) //當執行緒還在工作的時候,程序不能結束 } class MyTest{ //重寫finalize /* * 正常情況下,這個函式是由系統自動呼叫的,重寫它是為了觀察多執行緒的實現 * 正常情況下,當MyTest的物件被釋放的時候,會自動呼叫他的finalize方法 */ protected void finalize()throws Throwable{ //正常的這裡其實有父類的方法...進行垃圾回收 System.out.println("finalize"); } }
/* * 預設情況下,主執行緒和垃圾回收執行緒都是由系統建立的,但是我們需要完成自己的 * 功能---所以要建立自己的執行緒物件。 * java將執行緒面向物件了,形成的類就是Thread,在Thread類內部執行任務的方法叫run() * 注意:如果想要run作為任務區,必須讓他去被自動呼叫,我們通過執行start方法,來實現run()方法的呼叫 * 其實呼叫start()方法相當於開啟這個執行緒,start方法會自動呼叫run()方法,相當於在該執行緒上跑任務(run方法內的程式) */ public class Demo8 { public static void main(String[] args) {//兩個。垃圾回收執行緒和主執行緒, //注:一般會將垃圾回收執行緒忽略掉 // //1.通過Thread類直接建立執行緒 // Thread中的run()裡並沒有任何程式碼 // Thread t1=new Thread(); // Thread t2=new Thread(); // //呼叫start(),開啟執行緒 // t1.start();//此時有兩個執行緒 // t2.start();//此時有三個執行緒 // System.out.println("main"); //2通過Thread類的子類建立執行緒 MyThread t1=new MyThread("xiaote");//建立了一個執行緒 thread-0 MyThread t2=new MyThread("xiaosan");//建立了一個執行緒 thread-1 //呼叫start(),開啟執行緒 t1.start();//此時有兩個執行緒 t2.start();//此時有三個執行緒 System.out.println("main"); for(int i=1;i<=10;i++) { System.out.println(Thread.currentThread().getName()+" "+" i: "+i); } //手動呼叫run方法,它只是一個普通的方法,沒有開啟執行緒,只是在主執行緒中跑完了run方法裡的內容 t1.run(); } } //寫 Thread類的子類,因為Thread類的run()方法是空的,無法實現具體的任務, //所以用建立子類的方式去實現我們自己的功能,作為Thread子類也是執行緒類 class MyThread extends Thread{ String myname; /* * 重寫run()方法作為執行緒的任務區,完成我們的功能 * Thread.currentThread()獲取的是當前的任務區所線上程的物件 * getName():獲取執行緒的名字 */ public MyThread(String myname) { this.myname=myname; } public void run() { for(int i=1;i<=10;i++) { System.out.println(Thread.currentThread().getName()+" "+myname+" i: "+i); } } }
//------下面兩個例子還沒有弄好
/* * 例項:四個售票員賣票 * 分析:建立4個執行緒--四個售票員 * 一份資料 * 實現多執行緒的兩種方式: * 第一種方式:通過建立Thread子類的方式實現功能---執行緒與任務繫結在了一起 * 第二種:將任務從執行緒中分離出來,哪個執行緒需要工作,就將任務交給誰,操作方便 * */ //第一種方式:通過建立Thread子類的方式實現功能---執行緒與任務繫結在了一起 public class Demo9 { public static void main(String[] args) { // //建立四個執行緒 // Seller s1=new Seller(); // Seller s2=new Seller(); // Seller s3=new Seller(); // Seller s4=new Seller(); // // //開啟執行緒 // s1.start(); // s2.start(); // s3.start(); // s4.start(); //第二種:將任務從執行緒中分離出來 //1先建立任務類物件 Ticket ticket=new Ticket(); //2建立執行緒物件,並將任務交給執行緒 Thread t1=new Thread(ticket); //裡面自帶一個run()然後Ticket裡也有一個run() //如果有Runnble的run方法,就會執行Runnale的run方法 //沒有Thread中的裡面什麼都沒有的run()方法 //所以說明任務類中的run方法優先順序高於Thread內部的run() Thread t2=new Thread(ticket); Thread t3=new Thread(ticket); Thread t4=new Thread(ticket); //3開啟執行緒 t1.start(); t2.start(); t3.start(); t4.start(); } } //建立任務類 class Ticket implements Runnable{ //所有的物件共享num int num=40; @Override public void run() { for(int i=0;i<10;i++) { System.out.println(Thread.currentThread().getName()+" "+i+" "+(--num)); } } } //建立Thread的子類 //class Seller extends Thread{ // //所有的物件共享num // static int num=20; // public void run() { // for(int i=0;i<5;i++) { // System.out.println(Thread.currentThread().getName()+" "+i+" "+(--num)); // } // } // }
public class Demo10 {
public static void main(String[] args) {
//執行緒的其他知識點
//1
Thread t1=new Thread();
Thread t2=new Thread(t1);
//將t2當做任務處理了,因為Thread實現了Runable介面
t1.start();//呼叫的是t1的run()方法
t2.start();//呼叫的也是t1的run()方法
//2匿名子類物件也可以工作
new Thread();//匿名物件
new Thread() {
public void run() {}
//這裡重寫了run()但其實Thread類本身裡面就有run(){}
}.run();//匿名子類物件,該物件的父類是Thread
//直接呼叫run()沒有用開啟執行緒,這裡run()就是普通的方法
//正確的方式:
new Thread() {
public void run() {}
//這裡重寫了run()但其實Thread類本身裡面就有run(){}
}.start();
}
}