多線程(多窗口賣票實例講解)
實現(xiàn)多線程的方式:
實現(xiàn)多線程的方式有多種,這里只列舉兩種常用的,而第一種繼承Thread的方式無法實現(xiàn)多窗口賣票。
一,繼承Thread方式:
特點:多線程多實例,無法實現(xiàn)資源的共享。
例子:
package com.demo.study.multithreading;
public class MyThread extends Thread{
private int i = 10;
// 可以自行定義鎖,也可以使用實例的鎖
Object mutex = new Object();
public void selltickets(){
synchronized (mutex) {
if(i>0){
i--;
//getName()獲取線程的名字
System.out.println(Thread.currentThread().getName()+" :"+ i);
}
}
}
@Override
public void run() {
while(i>0){
selltickets();
}
}
}
啟動線程:
package com.demo.study.multithreading;
public class Test {
public static void main(String[] args) {
//繼承Thread方式:多線程多實例,無法實現(xiàn)資源的共享
MyThread myThread1 = new MyThread();
MyThread myThread2 = new MyThread();
//給線程命名
myThread1.setName("線程1");
myThread2.setName("線程2");
myThread1.start();
myThread2.start();
}
}
運行結(jié)果:

二,實現(xiàn)Runnable方式:
特點:多線程單實例,可實現(xiàn)資源的共享
例子:實現(xiàn)多窗口賣票:
package com.demo.study.multithreading;
public class MyThreadImpl implements Runnable {
private int tickets = 10;
public void sellTickets() {
synchronized (MyThreadImpl.class) {
if (tickets > 0) {
tickets--;
System.out.println(Thread.currentThread().getName() + "正在賣票,還剩下" + tickets + "張");
}
}
}
@Override
public void run() {
while (tickets > 0) {
sellTickets();
try {
// 休眠一秒,讓執(zhí)行的效果更明顯
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
啟動線程:
注意:Thread中的start()方法是線程的就緒,而線程的啟動,需要等待CPU的調(diào)度(也就是所謂的線程搶資源);run()方法的方法體代表了線程需要完成的任務,稱之為線程執(zhí)行體。
void start() 使該線程開始執(zhí)行;Java 虛擬機調(diào)用該線程的 run 方法。
package com.demo.study.multithreading;
public class Test {
public static void main(String[] args) {
//只創(chuàng)建一個實例
MyThreadImpl threadImpl = new MyThreadImpl();
//將上面創(chuàng)建的唯一實例放入多個線程中,Thread類提供了多個構(gòu)造方法,見下圖(構(gòu)造方法摘要)
Thread thread1 = new Thread(threadImpl, "窗口1");
Thread thread2 = new Thread(threadImpl, "窗口2");
thread1.start();
thread2.start();
}
}
| 構(gòu)造方法摘要 | |
|---|---|
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 對象。 |
|
運行結(jié)果:

三、同步鎖與資源共享:
CPU可能隨機的在多個處于就緒狀態(tài)中的線程中進行切換,這時就可能出現(xiàn)線程的安全問題;線程安全問題,其實是指多線程環(huán)境下對共享資源的訪問可能會引起此共享資源的不一致性,而解決安全問題則需要同步鎖的加入,執(zhí)行synchronized部分代碼的時候必須需要對象鎖,而一個對象只有一個鎖,只有執(zhí)行完synchronized里面的代碼后釋放鎖,其他線程才可以獲得鎖,那么就保證了同一時刻只有一個線程訪問synchronized里面的代碼。實現(xiàn)資源共享的關鍵是,只有一個實例,synchronized使用的是同一把鎖,用實例的鎖或者定義一個實例。這就需要使用實現(xiàn)Runnable接口的方式,實現(xiàn)多線程,這樣傳入的是一個實例。繼承Thread的方式,傳入的是多個實例,每個實例都有一個鎖,那就無法實現(xiàn)控制。
以上這篇多線程(多窗口賣票實例講解)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
struts+spring+hibernate三個框架的整合
這篇文章主要介紹了struts+spring+hibernate三個框架的整合,需要的朋友可以參考下2017-09-09
Java中的JPA實體關系:JPA一對一,一對多(多對一),多對多
Java Persistence API(JPA)是Java平臺上的一個對象關系映射(ORM)規(guī)范,用于簡化數(shù)據(jù)庫操作,其中實體關系的映射是核心內(nèi)容之一,本文將深入淺出地探討JPA中的三種基本實體關系類型:一對一、一對多、多對多,揭示常見問題、易錯點及其避免策略,希望能幫助大家2024-06-06
關于Intellij IDEA中的Version Control問題
這篇文章主要介紹了Intellij IDEA中的Version Control問題,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-11-11
基于Java實現(xiàn)計數(shù)排序,桶排序和基數(shù)排序
這篇文章主要為大家詳細介紹了計數(shù)排序,桶排序和基數(shù)排序的多種語言的實現(xiàn)(JavaScript、Python、Go語言、Java),感興趣的小伙伴可以了解一下2022-12-12
SpringCloud服務網(wǎng)關Gateway的使用教程詳解
SpringCloud Gateway是Spring體系內(nèi)的一個全新項目,它旨在為微服務架構(gòu)提供一種簡單有效的統(tǒng)一的API路由管理方式。本文就來為大家詳細講講Gateway的使用教程,需要的可以參考一下2022-09-09

