首頁 > Java > java教程 > Thread、執行緒創建的實例教程

Thread、執行緒創建的實例教程

零下一度
發布: 2017-06-25 09:35:59
原創
1585 人瀏覽過

主執行緒:執行主方法的執行緒,就叫做主執行緒

單執行緒程式:程式從mani開始從上到下依序執行

 程式從main方法開始運作,JVM運行main方法,會找作業系統
 開闢一條通往cpu的執行路徑,cpu可以透過這條路徑來執行main方法
 這條路徑有一個名字叫主(main)執行緒

建立執行緒方式一繼承Thread類別
#  實作步驟:
1.建立Thread類別的子類別
2.重寫Thread類別中的run方法,設定執行緒的任務
3.建立Thread類別的子類別物件
4.呼叫Thread類別中的start方法開啟一個新的執行緒,執行run方法
使該執行緒開始執行;Java 虛擬機器呼叫該執行緒的run 方法。
結果是兩個執行緒並發地運行;目前執行緒(main執行緒)和另一個執行緒(執行 run 方法的執行緒)。
多次啟動一個執行緒是非法的。特別是當執行緒已經結束執行後,不能再重新啟動。

列印的結果出現了隨機性:
開啟兩個執行緒,對於cpu就選擇權利
喜歡誰,就執行誰,所以就出現了隨機性結果

 1 public class MyThread extends Thread{ 2     /* 3      * 2.重写Thread类中的run方法,设置线程的任务 4      * 开启这个线程要干什么事情 5      */ 6     @Override 7     public void run() { 8         for (int i = 0; i < 50; i++) { 9             System.out.println("run..."+i);10         }11     }12 }13     public static void main(String[] args) {14         //3.创建Thread类的子类对象15         MyThread mt = new MyThread();16         //mt.run();//不会开启线程,还是单线程程序17         //4.调用Thread类中的start方法开启一个新的线程,执行run方法18         mt.start();19         20         new MyThread().start();21         22         for (int i = 0; i < 50; i++) {23             System.out.println("main..."+i);24         }25     }
登入後複製

執行緒的名稱:
主執行緒:"main"
開啟的其它執行緒的名稱:"Thread-0","Thread-1"....

#取得執行緒的名稱
1.Thread類別中的方法getName
String getName() 傳回該執行緒的名稱。
2.Thread類別中的靜態方法,取得目前正在執行的執行緒
static Thread currentThread() 傳回目前正在執行的執行緒物件的參考。
設定執行緒的名稱:
1.Thread類別中的方法setName(String name)
void setName(String name) 改變執行緒名稱,使其與參數 name 相同。
2.子類別加入帶參構造,呼叫父類別Thread類別的帶參建構方法,傳遞執行緒的名稱,讓父類別給線程取名字(讓父親給兒子取名字)
Thread(String name ) 分配新的Thread 物件。


建立執行緒方式—實作Runnable介面

實作步驟:
1.建立Runnable介面的實作類別
2.重寫Runnable介面中的run方法,設定執行緒任務
3.建立Runnable介面的實作類別物件
4.建立Thread類別物件,建構方法中傳入Runnable介面的實作類別
Thread(Runnable target) 指派新的Thread 物件。
5.呼叫Thread類別中的方法start,開啟執行緒執行run方法


實作Runnable的好處
1.避免了類別繼承Thread類別之後,無法繼承其它的類別(單一繼承的限制)
2.把設定執行緒任務,和開啟執行緒進行解耦,增強了擴展性
實作類別的作用:就是設定執行緒任務
Thread類別的作用:開啟執行緒
好處:傳遞不同的實作類別,實作類別重寫的方法不一樣,可以呼叫不同的方法

#執行緒的匿名內部類別使用

   匿名:沒有名字
   內部類別:寫在其他類別內部的類別(成員位置:成員內部類別,局部位置(方法中):局部內部類別)

   匿名內部類別的格式:
    new 父類別/介面() {
    重寫父類別/介面中的方法;
    };

   多執行緒的父類別:
    Thread
    Runnable

##rrrereee
以上一堆程式碼就是一個建立子類別重寫父類別方法的過程
相當於: new MyThread().start();


#程式出現了執行緒安全問題:賣了重複的票與不存在的票

解決方案:
第一種方式:可以使用同步程式碼區塊

synchronized(鎖定物件){
產生安全性問題的程式碼;
存取了共享資料的程式碼;
}

注意:
必須保證多個執行緒使用的是同一個鎖定對象
//在成員位置上建立一個鎖定對象(保證唯一)

1  new Thread(){2             //重写run方法,设置线程任务3             @Override4             public void run() {5                 for (int i = 0; i < 20; i++) {6                     System.out.println(Thread.currentThread().getName()+":"+i);7                 }8             }9         }
登入後複製

程式出現了線程安全問題:賣了重複的票和不存在的票

   解決方案:
    第二種方式:同步方法

   使用步驟:
    1.把可能出現安全問題的程式碼抽取到一個方法中
    2.把方法增加一個關鍵字synchronized
    修飾符synchronized synchronized
    修飾符synchronized synchronized 返回值類型方法名稱(參數){
    可能出現安全問題的程式碼;
    存取了共享資料的程式碼;
    }

   同步方法所使用的鎖定物件是什麼?
#    所使用的##    同步方法所使用的鎖定物件是什麼?
#    所使用的使用的「就是本類別物件new RunnableImpl()-->叫this

   靜態的同步方法,使用時什麼鎖定物件?
   使用的是本類別物件的class屬性(反射)
   RunnableImpl .class

 1 Object obj = new Object(); 2      3     @Override 4     public void run() { 5         //让卖票重复执行 6         while(true){ 7          8              * 同步代码块 9              * 程序会频繁的判断锁,获取锁,释放锁,所以会降低速度10              11             synchronized (obj) {12                 if(ticket>0){13                     //为了提高安全问题的概率,让程序睡眠14                     try {15                         Thread.sleep(10);16                     } catch (InterruptedException e) {17                         e.printStackTrace();18                     }19                     //卖票ticket--20                     System.out.println(Thread.currentThread().getName()+"...卖第"+ticket--+"张票");21                 }22             }23         }24     }
登入後複製
#

程序出现了线程安全问题:卖了重复的票和不存在的票
*
* 解决方案:
* 第三种方式:使用Lock接口,JDK1.5之后出现的
*
* java.util.concurrent.locks.Lock接口
* 方法:
* void lock() 获取锁。
* void unlock() 释放锁。  
*  接口的实现类:ReentrantLock
*  
* 实现步骤:
* 1.在成员位置创建一个Lock接口的实现类对象ReentrantLock
* 2.在可能出现线程安全问题的代码前,调用lock方法获取锁
* 3.在可能出现线程安全问题的代码后,调用unlock方法释放锁
*
*1.在成员位置创建一个Lock接口的实现类对象ReentrantLock
Lock l = new ReentrantLock();

 1 @Override 2     public void run() { 3         //让卖票重复执行 4         while(true){ 5             //2.在可能出现线程安全问题的代码前,调用lock方法获取锁 6             l.lock(); 7                 if(ticket>0){ 8                     //为了提高安全问题的概率,让程序睡眠 9                     try {10                         Thread.sleep(10);11                         //卖票ticket--12                         System.out.println(Thread.currentThread().getName()+"...卖第"+ticket--+"张票");13                     } catch (InterruptedException e) {14                         e.printStackTrace();15                     }finally {16                         //3.在可能出现线程安全问题的代码后,调用unlock方法释放锁17                         l.unlock();    
18                     }19                 }20         }
登入後複製

 

以上是Thread、執行緒創建的實例教程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門推薦
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板