1.用思惟導圖對java多線程的學習內容進行總結。
2.下面是一個單線程實現的龜兔賽跑遊戲。java
public class TortoiseHareRace { public static void main(String[] args) { int totalStep = 10; int tortoiseStep = 0; int hareStep = 0; boolean[] flags = {true,false}; System.out.println("龜兔賽跑開始了..."); while(tortoiseStep < totalStep && hareStep < totalStep){ tortoiseStep++; System.out.println("烏龜跑了"+tortoiseStep+"步..."); boolean isHareSleep = flags[((int)(Math.random()*10))%2]; if(isHareSleep){ System.out.println("兔子睡着了zzzz"); }else{ hareStep += 2; System.out.println("兔子跑了"+hareStep+"步..."); } } } }
閱讀程序,採用實現Runnable接口的方式用多線程實現這個小遊戲。下面給出主線程類,補充Tortoise線程類和Hare線程類。git
public class TortoiseHareRace { public static void main(String[] args) { Tortoise tortoise = new Tortoise(10); Hare hare = new Hare(10); Thread tortoiseThread = new Thread(tortoise); Thread hareThread = new Thread(hare); tortoiseThread.start(); hareThread.start(); } } class Tortoise implements Runnable { private int i; private int totalStep = 10; private int tortoiseStep = 0; public Tortoise(int i) { this.i=i; } public void run() { while(tortoiseStep < totalStep ){ synchronized(this){ tortoiseStep++; System.out.println("烏龜跑了"+tortoiseStep+"步..."); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } } } } class Hare implements Runnable{ private int i; boolean[] flags = {true,false}; private int totalStep = 10; private int hareStep = 0; public Hare(int i) { this.i=i; } public void run() { while( hareStep < totalStep){ synchronized(this){ try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } boolean isHareSleep = flags[((int)(Math.random()*10))%2]; if(isHareSleep){ System.out.println("兔子睡着了zzzz"); } else{ hareStep += 2; System.out.println("兔子跑了"+hareStep+"步..."); } } } } }
3.下面的程序是模擬了生產者——消費者問題,生產者生產10個數,消費者依次消費10個數,運行程序,看結果是否正常?存在什麼問題?說明緣由。使用synchronized, wait, notify解決程序出現的問題。寫出修改的部分程序便可。正則表達式
class Consumer implements Runnable { private Clerk clerk; public Consumer(Clerk clerk) { this.clerk = clerk; } public void run() { System.out.println("消費者開始消耗整數......"); // 消耗10個整數 for(int i = 1; i <= 10; i++) { try { // 等待隨機時間 Thread.sleep((int) (Math.random() * 3000)); } catch(InterruptedException e) { e.printStackTrace(); } clerk.getProduct();// 從店員處取走整數 } } } class Producer implements Runnable { private Clerk clerk; public Producer(Clerk clerk) { this.clerk = clerk; } public void run() { System.out.println( "生產者開始生產整數......"); // 生產1到10的整數 for(int product = 1; product <= 10; product++) { try { Thread.sleep((int) Math.random() * 3000); } catch(InterruptedException e) { e.printStackTrace(); } clerk.setProduct(product); // 將產品交給店員 } } } public class ProductTest { public static void main(String[] args) { Clerk clerk = new Clerk(); Thread consumerThread = new Thread(new Consumer(clerk)); Thread producerThread = new Thread(new Producer(clerk)); consumerThread.start(); producerThread.start(); } } class Clerk { private int product = -1; // -1 表示目前沒有產品 // 這個方法由生產者呼叫 public void setProduct(int product) { this.product = product; System.out.printf("生產者設定 (%d)%n", this.product); } // 這個方法由消費者呼叫 public int getProduct() { int p = this.product; System.out.printf("消費者取走 (%d)%n", this.product); return p; } }
運行結果不正常
緣由:線程運行不肯定,沒有進行同步,喚醒和等待。
修改以下:數據庫
class Consumer implements Runnable { private Clerk clerk=null; public Consumer(Clerk clerk) { this.clerk = clerk; } public void run() { // 消耗10個整數 for(int i = 1; i <= 10; i++) { clerk.get(); System.out.printf("消費者取走 (%d)%n", i); try{ Thread.sleep(60) ; } catch(InterruptedException e){ e.printStackTrace(); } } } } class Producer implements Runnable { private Clerk clerk; public Producer(Clerk clerk) { this.clerk = clerk; } public void run() { // 生產1到10的整數 for(int product = 1; product <= 10; product++) { clerk.set(product); // 將產品交給店員 System.out.printf("生產者設定 (%d)%n", product); } try { Thread.sleep(60); } catch(InterruptedException e) { e.printStackTrace(); } } } class Clerk { private int product = -1; // -1 表示目前沒有產品 // 這個方法由生產者呼叫 private boolean flag =false; public synchronized void set(int product) { if(!flag){ try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } flag=false; super.notify(); } // 這個方法由消費者呼叫 public synchronized void get() { if(flag){ try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } flag=true; super.notify(); } }
實驗內容:
1.模擬三個老師同時分發80分做業,每一個老師至關於一個線程。
格式以下:設計模式
程序設計思路:設計一個Sale的類,繼承Runnable,重寫run方法,在run方法中進行輸出。數組
public void run(){ while(homework>0){ System.out.println( Thread.currentThread().getName()+"正在發第" +homework--+"份做業" ); }
}
設計一個測試類,在測試類中定義Sale的對象,定義線程並運行。多線程
2.模擬一個銀行存款的程序。假設有兩個儲戶都去銀行往同一個帳戶進行存款,一次存100,每人存三次。要求儲戶每存一次錢,帳戶餘額增長100,並在控制檯輸出當前帳戶的餘額。
格式以下:dom
程序設計思路:
設計一個Bank類,定義一個存儲帳戶餘額的變量以及一個存款的方法,輸出帳戶餘額。學習
public void add(int money){ account =account+money; System.out.println("帳戶餘額爲:"+account); }
設計一個Depositor類,實現向帳戶存款3次。定義一個Bank的屬性,重寫run方法。測試
public void run(){ synchronized(obj){ for(int i=0;i<3;i++){ accont.add(100); } } }
設計一個測試類,建立客戶對象,啓動線程。
Depositor mt1=new Depositor(); Thread t1=new Thread(mt1); Thread t2=new Thread(mt1); t1.start(); t2.start();
碼雲commit歷史截圖
代碼行數(新增/累積) | 學習時間(新增/累積) | 本週學習內容 | |
---|---|---|---|
目標 | 5000行 | 300小時 | |
第2-4周 | 100/100 | 20/20 | 學習了數組和方法 |
第5周 | 200/300 | 30/50 | 學習了String類和StringBuffer類 |
第6周 | 800/1100 | 40/90 | 學習了this、static關鍵字,Singleton模式 |
第八週 | 1200/1700 | 60/110 | 繼承和多態,抽象方法 |
第九周 | 1500/2000 | 10/120 | 接口、工廠設計模式、包裝類、匿名內部類、日期類、正則表達式 |
第十週 | 1900/2400 | 10/130 | 異常處理、泛型、集合 |
第十一週 | 2500/3000 | 20/150 | 用戶圖形界面、事件處理 |
第十二週 | 500/3500 | 10/160 | JDBC數據庫的連接 |
第十三週 | 800/4300 | 50/210 | java io |
第十四周 | 300/4600 | 20/220 | 多線程 |