黑馬程式員系列第二篇 多線程(2),黑馬第二篇

來源:互聯網
上載者:User

黑馬程式員系列第二篇 多線程(2),黑馬第二篇

 ASP.Net+Android+IOS開發  、Net培訓、期待與您交流!

 

(前言:本篇文章主要依據畢向東老師的課程視頻整理而成,如要詳細學習,請觀看畢老師視頻  百度網盤連結地址:http://pan.baidu.com/s/1i3m6DrJ)

 

目錄:1、線程通訊--生產消費者樣本(線程通訊安全、等待喚醒機制)    2、停止線程、及其會出現的問題、及解決的辦法    3、守護線程及幾個Thread的方法                   4、工作中線程的常見寫法

1、線程通訊--生產消費者樣本

程式碼範例:

1 public class ProducerConsumer { 2 //需求:生產和消費行為依次進行。 設定產品為BMW 設定生產者和消費者線程各兩個 3 public static void main(String[] args) { 4 5 Product pro=new Product(); 6 7 new Thread(new Producter(pro)).start(); 8 new Thread(new Consumer(pro)).start(); 9 new Thread(new Producter(pro)).start();10 new Thread(new Consumer(pro)).start();11 12 }13 }14 class Product{15 16 private String name;17 private int No=1;18 boolean flag=false;19 20 public synchronized void set(String names){21 while(flag)22 try {23 this.wait();//等待狀態 24 } catch (InterruptedException e) {25 e.printStackTrace();26 } 27 this.name=names+"---"+this.No++;28 System.out.println(this.name+"---被"+Thread.currentThread().getName()+"生產"); 29 flag=true;30 this.notifyAll();//喚醒所有線程31 } 32 public synchronized void out(){33 while(!flag)34 try {35 this.wait();//等待狀態36 } catch (InterruptedException e) {37 e.printStackTrace();38 } 39 System.out.println(this.name+"---被"+Thread.currentThread().getName()+"消費了-------"); 40 flag=false;41 this.notifyAll();//喚醒所有線程42 }43 }44 //生產者45 class Producter implements Runnable{46 private Product p;47 public Producter(Product pr){48 this.p=pr;49 }50 public void run(){ 51 while(true){52 p.set("BMW");53 }54 } 55 }56 //消費者57 class Consumer implements Runnable{58 private Product p;59 public Consumer(Product pr){60 this.p=pr;61 } 62 public void run(){ 63 while(true){64 p.out();65 }66 }67 }View Code

 

 

使用JDK5.0新特性改進後的代碼

1 /*JDK5.0後增加了Lock 和Condition新類特性來取代 同步和鎖的繁瑣操作 */ 2 public class ProducerConsumerNew { 3 4 public static void main(String[] args) { 5 6 Product pro=new Product(); 7 8 new Thread(new Producter(pro)).start(); 9 new Thread(new Consumer(pro)).start();10 new Thread(new Producter(pro)).start();11 new Thread(new Consumer(pro)).start();12 13 }14 15 }16 class ProductNew{ 17 private String name;18 private int No=1;19 boolean flag=false;20 21 private Lock lock=new ReentrantLock();22 private Condition con1=lock.newCondition();23 private Condition con2=lock.newCondition();24 25 public void set(String name){26 27 while(flag)28 try {29 lock.lock();30 con1.wait();31 } catch (InterruptedException e) {32 e.printStackTrace();33 }finally{34 lock.unlock();35 }36 this.name=name+"---"+this.No++; 37 System.out.println(this.name+"---被"+Thread.currentThread().getName()+"生產");38 39 this.flag=true;40 con2.signal();41 }42 43 public void out(){ 44 while(!this.flag)45 try {46 lock.lock();47 con2.wait();48 } catch (InterruptedException e) {49 e.printStackTrace();50 }finally{51 lock.unlock();52 con1.signal();53 } 54 System.out.println(this.name+"---被"+Thread.currentThread().getName()+"消費了-------");55 56 this.flag=false;57 }58 }59 //生產者60 class ProducterNew implements Runnable{61 private ProductNew p;62 public ProducterNew(ProductNew pr){63 this.p=pr;64 }65 public void run(){66 while(true){67 p.set("BMW");68 }69 } 70 }71 //消費者72 class ConsumerNew implements Runnable{73 private ProductNew p;74 public ConsumerNew(ProductNew pr){75 this.p=pr;76 } 77 public void run(){78 while(true)79 p.out();80 }81 } View Code

 

  

2、停止線程、及其會出現的問題、及解決的辦法    

停止線程思路:開啟多線程運行,運行代碼通常是迴圈結構,只要控制住迴圈,就可以讓run()方法結束,線程即結束。

特殊情況:當線程處於凍結狀態(wait()),就不會讀取到標記,那麼線程就不會結束。

解決辦法:當沒有指定的方式讓凍結的線程恢複到運行狀態時,需要用Interrupt()方法強制清除凍結狀態,再用操作標記讓線程結束 

 

一個簡單的代碼例子

1 public class ThreadStop { 2 3 public static void main(String[] args) { 4 5 ThreadTt tt=new ThreadTt(); 6 7 Thread th1=new Thread(tt); 8 Thread th2=new Thread(tt); 9 th1.start();10 th2.start();11 int count=0;12 while(true){13 if(++count>60){ //迴圈來控制線程的結束14 th1.interrupt(); //強制清除線程凍結狀態15 th2.interrupt();16 break;17 }18 System.out.println(Thread.currentThread().getName()+"....run---"+count);19 } 20 System.out.println(Thread.currentThread().getName()+"....over");21 }22 }23 class ThreadTt implements Runnable{24 25 boolean flag=true;26 Lock lock=new ReentrantLock();27 Condition con=lock.newCondition();28 public synchronized void run() {29 30 while(flag){31 try {32 wait(); //用這個方法讓線程處於凍結狀態33 } catch (InterruptedException e) {34 System.out.println(e.getStackTrace());35 flag=false;36 }37 System.out.println(Thread.currentThread().getName()+"...run");38 }39 }40 }View Code

 

 

 

3、守護線程及幾個Thread的方法

 

守護線程/使用者線程:通俗而言為”後台進程”,當前台進程都結束時,後台進程自動結束;當正在啟動並執行線程都是守護線程時,JVM自動結束。     

 

setDaemon()方法設定守護線程,該方法必須在啟動線程前調用

 

 

Join()方法  特點:當A線程執行到了B線程的jion()方法是,A就會等待,等B線程都執行完以後,A才會執行。Jion可以用來臨時加入線程執行    線程搶奪cpu執行權

 

ToString()方法

 

setPriority()方法 更改線程的優先順序,優先順序代表搶奪資源的頻率高低

 

Yield()方法  暫停當前線程的執行,去執行其它線程

 

4、工作中線程的常見寫法(用到內部類)

不多說,看代碼

 

1 public class ThreadStand { 2 3 public static void main(String[] args) { 4 //工作中多線程的常見寫法,構建內部類 5 new Thread(){ 6 public void run(){ 7 for(int i=0;i<100;i++) 8 System.out.println(Thread.currentThread().getName()+"....run...."+i); 9 }10 }.start();11 12 for(int i=0;i<100;i++)13 System.out.println(Thread.currentThread().getName()+"....run...."+i);14 15 //構造內部類16 Runnable rn= new Runnable(){17 public void run() {18 for(int i=0;i<100;i++)19 System.out.println(Thread.currentThread().getName()+"....run...."+i); 20 }21 }; 22 new Thread(rn).start(); 23 }24 }View Code

 

 

 

       

       初學者難免錯誤,歡迎評判指教,持續更正ing...........

 

ASP.Net+Android+IOS開發  、Net培訓、期待與您交流!

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.