1. 程式人生 > >多線程(多窗口賣票例子)

多線程(多窗口賣票例子)

dem set lan ccf extends end 結果 ren get

實現多線程的方式:

實現多線程的方式有多種,這裏只列舉兩種常用的,而第一種繼承Thread的方式無法實現多窗口賣票。

一,繼承Thread方式:

特點:多線程多實例,無法實現資源的共享。

例子:

 1 package com.demo.study.multithreading;
 2 
 3 public class MyThread extends Thread{
 4 
 5     private int i = 10;
 6     // 可以自行定義鎖,也可以使用實例的鎖
 7     Object mutex = new Object();
 8     public void selltickets(){
9 10 synchronized (mutex) { 11 12 if(i>0){ 13 i--; 14 //getName()獲取線程的名字 15 System.out.println(Thread.currentThread().getName()+" :"+ i); 16 } 17 } 18 } 19 20 @Override 21 public void run() { 22 while
(i>0){ 23 24 selltickets(); 25 } 26 } 27 }

啟動線程:

 1 package com.demo.study.multithreading;
 2 
 3 public class Test {
 4 
 5     public static void main(String[] args) {
 6 //繼承Thread方式:多線程多實例,無法實現資源的共享
 7         MyThread myThread1 = new MyThread();
 8         MyThread myThread2 = new
MyThread(); 9 //給線程命名 10 myThread1.setName("線程1"); 11 myThread2.setName("線程2"); 12 myThread1.start(); 13 myThread2.start(); 14 } 15 }

運行結果:

技術分享

二,實現Runnable方式:

特點:多線程單實例,可實現資源的共享

例子:實現多窗口賣票:

 1 package com.demo.study.multithreading;
 2 
 3 public class MyThreadImpl implements Runnable {
 4 
 5     private int tickets = 10;
 6 
 7     public void sellTickets() {
 8 
 9         synchronized (MyThreadImpl.class) {
10             if (tickets > 0) {
11 
12             tickets--;
13             System.out.println(Thread.currentThread().getName() + "正在賣票,還剩下" + tickets + "張");
14             }
15         }
16     }
17 
18     @Override
19     public void run() {
20 
21         while (tickets > 0) {
22             sellTickets();
23             try {
24                 // 休眠一秒,讓執行的效果更明顯
25                 Thread.sleep(100);
26             } catch (InterruptedException e) {
27                 e.printStackTrace();
28             }
29         }
30     }
31 }

啟動線程:

註意:線程的啟動是通過Thread中的start()方法,而線程的啟動,只運行了實例類中的重寫的run()方法。

void start()
使該線程開始執行;Java 虛擬機調用該線程的 run 方法。
 1 package com.demo.study.multithreading;
 2 
 3 public class Test {
 4 
 5     public static void main(String[] args) {
 6 
 7         //只創建一個實例
 8         MyThreadImpl threadImpl = new MyThreadImpl();
 9         //將上面創建的唯一實例放入多個線程中,Thread類提供了多個構造方法,見下圖(構造方法摘要)
10         Thread thread1 = new Thread(threadImpl, "窗口1");
11         Thread thread2 = new Thread(threadImpl, "窗口2");
12         thread1.start();
13         thread2.start();
14         
15     }
16 }

構造方法摘要
Thread()
分配新的 Thread 對象。
Thread(Runnable target)
分配新的 Thread 對象。
Thread(Runnable target, String name)
分配新的 Thread 對象。
Thread(String name)
分配新的 Thread 對象。
Thread(ThreadGroup group, Runnable target)
分配新的 Thread 對象。
Thread(ThreadGroup group, Runnable target, String name)
分配新的 Thread 對象,以便將 target 作為其運行對象,將指定的 name 作為其名稱,並作為 group 所引用的線程組的一員。
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
分配新的 Thread 對象,以便將 target 作為其運行對象,將指定的 name 作為其名稱,作為 group 所引用的線程組的一員,並具有指定的堆棧大小
Thread(ThreadGroup group, String name)
分配新的 Thread 對象。

運行結果:

技術分享

三、同步鎖與資源共享:

  執行synchronized部分代碼的時候必須需要對象鎖,而一個對象只有一個鎖,只有執行完synchronized裏面的代碼後釋放鎖,其他線程才可以獲得鎖,那麽就保證了同一時刻只有一個線程訪問synchronized裏面的代碼。實現資源共享的關鍵是,只有一個實例,synchronized使用的是同一把鎖,用實例的鎖或者定義一個實例。這就需要使用實現Runnable接口的方式,實現多線程,這樣傳入的是一個實例。繼承Thread的方式,傳入的是多個實例,每個實例都有一個鎖,那就無法實現控制。

多線程(多窗口賣票例子)