1.用思惟導圖對java多線程的學習內容進行總結。
java
2.下面是一個單線程實現的龜兔賽跑遊戲。git
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線程類。多線程
補充以後的程序:dom
class Tortoise implements Runnable { private int tortoiseStep = 0; private int totalStep=10; public Tortoise(int tortoiseStep) { this.tortoiseStep=tortoiseStep; } public void run() { while(tortoiseStep < this.totalStep) { tortoiseStep++; System.out.println( "烏龜跑了" + tortoiseStep + "步" ); } } } class Hare implements Runnable { private int hareStep = 0; private int totalStep=10; boolean[] flags = {true,false}; public Hare(int hareStep) { this.hareStep=hareStep; } public void run() { while(hareStep < this.totalStep) { boolean isHareSleep = flags[((int)(Math.random()*10))%2]; if (isHareSleep) { System.out.println("兔子睡着了zzzz"); } else { hareStep += 2; System.out.println("兔子跑了" + hareStep + "步..."); } } } } public class TortoiseHareRace { public static void main(String[] args) { Tortoise tortoise = new Tortoise(0); Hare hare = new Hare(0); System.out.println("龜兔賽跑開始了..."); Thread tortoiseThread = new Thread(tortoise); Thread hareThread = new Thread(hare); tortoiseThread.start(); hareThread.start(); } }
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; } }
運行結果爲:測試
消費者開始消耗整數...... 生產者開始生產整數...... 生產者設定 (1) 生產者設定 (2) 生產者設定 (3) 生產者設定 (4) 生產者設定 (5) 生產者設定 (6) 生產者設定 (7) 生產者設定 (8) 生產者設定 (9) 生產者設定 (10) 消費者取走 (10) 消費者取走 (10) 消費者取走 (10) 消費者取走 (10) 消費者取走 (10) 消費者取走 (10) 消費者取走 (10) 消費者取走 (10) 消費者取走 (10) 消費者取走 (10)
緣由:沒有同步、喚醒及等待this
修改以後的程序:.net
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(); } } } } 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); // 將產品交給店員 } } } class Clerk { private int product = -1; // -1 表示目前沒有產品 private int p ; // 這個方法由生產者呼叫 public synchronized void setProduct(int product) { if (this.product != -1) { try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.product = product; p = this.product; System.out.printf("生產者設定 (%d)%n", this.product); getProduct(); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } this.product = -1; super.notify(); } // 這個方法由消費者呼叫 public synchronized int getProduct() { if (this.product == -1) { try { super.wait(); }catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("消費者取走 (%d)%n", p); this.product = -1; super.notify(); return this.product; } }
運行結果爲:
消費者開始消耗整數......
生產者開始生產整數......
生產者設定 (1)
消費者取走 (1)
生產者設定 (2)
消費者取走 (2)
生產者設定 (3)
消費者取走 (3)
生產者設定 (4)
消費者取走 (4)
生產者設定 (5)
消費者取走 (5)
生產者設定 (6)
消費者取走 (6)
生產者設定 (7)
消費者取走 (7)
生產者設定 (8)
消費者取走 (8)
生產者設定 (9)
消費者取走 (9)
生產者設定 (10)
消費者取走 (10)線程
1.程序設計思路:建一個runnerble接口,定義做業的份數,利用線程來發放做業,建一個測試類,建立對象,啓動線程設計
問題:
class Person implements Runnable{ Bank b=new Bank(); private int sum=0; public void run(){ synchronized(b){ for(int i=0;i<3;i++){ try{ Thread.sleep(300); sum= b.add(); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println( Thread.currentThread().getName() +"正在存款,帳戶餘額爲:" + sum ); } } } }
緣由:不知道應該哪一個爲接口類
解決方案:後來查了一些資料,在銀行類定義增長方法,儲戶爲接口,調用方法,運行出來了。