多線程(多窗口賣(mài)票實(shí)例講解)
實(shí)現(xiàn)多線程的方式:
實(shí)現(xiàn)多線程的方式有多種,這里只列舉兩種常用的,而第一種繼承Thread的方式無(wú)法實(shí)現(xiàn)多窗口賣(mài)票。
一,繼承Thread方式:
特點(diǎn):多線程多實(shí)例,無(wú)法實(shí)現(xiàn)資源的共享。
例子:
package com.demo.study.multithreading;
public class MyThread extends Thread{
private int i = 10;
// 可以自行定義鎖,也可以使用實(shí)例的鎖
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();
}
}
}
啟動(dòng)線程:
package com.demo.study.multithreading;
public class Test {
public static void main(String[] args) {
//繼承Thread方式:多線程多實(shí)例,無(wú)法實(shí)現(xiàn)資源的共享
MyThread myThread1 = new MyThread();
MyThread myThread2 = new MyThread();
//給線程命名
myThread1.setName("線程1");
myThread2.setName("線程2");
myThread1.start();
myThread2.start();
}
}
運(yùn)行結(jié)果:

二,實(shí)現(xiàn)Runnable方式:
特點(diǎn):多線程單實(shí)例,可實(shí)現(xiàn)資源的共享
例子:實(shí)現(xiàn)多窗口賣(mài)票:
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() + "正在賣(mài)票,還剩下" + tickets + "張");
}
}
}
@Override
public void run() {
while (tickets > 0) {
sellTickets();
try {
// 休眠一秒,讓執(zhí)行的效果更明顯
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
啟動(dòng)線程:
注意:Thread中的start()方法是線程的就緒,而線程的啟動(dòng),需要等待CPU的調(diào)度(也就是所謂的線程搶資源);run()方法的方法體代表了線程需要完成的任務(wù),稱(chēng)之為線程執(zhí)行體。
void start() 使該線程開(kāi)始執(zhí)行;Java 虛擬機(jī)調(diào)用該線程的 run 方法。
package com.demo.study.multithreading;
public class Test {
public static void main(String[] args) {
//只創(chuàng)建一個(gè)實(shí)例
MyThreadImpl threadImpl = new MyThreadImpl();
//將上面創(chuàng)建的唯一實(shí)例放入多個(gè)線程中,Thread類(lèi)提供了多個(gè)構(gòu)造方法,見(jiàn)下圖(構(gòu)造方法摘要)
Thread thread1 = new Thread(threadImpl, "窗口1");
Thread thread2 = new Thread(threadImpl, "窗口2");
thread1.start();
thread2.start();
}
}
| 構(gòu)造方法摘要 | |
|---|---|
Thread() 分配新的 Thread 對(duì)象。 |
|
Thread(Runnable target) 分配新的 Thread 對(duì)象。 |
|
Thread(Runnable target, String name) 分配新的 Thread 對(duì)象。 |
|
Thread(String name) 分配新的 Thread 對(duì)象。 |
|
Thread(ThreadGroup group, Runnable target) 分配新的 Thread 對(duì)象。 |
|
Thread(ThreadGroup group, Runnable target, String name) 分配新的 Thread 對(duì)象,以便將 target 作為其運(yùn)行對(duì)象,將指定的 name 作為其名稱(chēng),并作為 group 所引用的線程組的一員。 |
|
Thread(ThreadGroup group, Runnable target, String name, long stackSize) 分配新的 Thread 對(duì)象,以便將 target 作為其運(yùn)行對(duì)象,將指定的 name 作為其名稱(chēng),作為 group 所引用的線程組的一員,并具有指定的堆棧大小。 |
|
Thread(ThreadGroup group, String name) 分配新的 Thread 對(duì)象。 |
|
運(yùn)行結(jié)果:

三、同步鎖與資源共享:
CPU可能隨機(jī)的在多個(gè)處于就緒狀態(tài)中的線程中進(jìn)行切換,這時(shí)就可能出現(xiàn)線程的安全問(wèn)題;線程安全問(wèn)題,其實(shí)是指多線程環(huán)境下對(duì)共享資源的訪問(wèn)可能會(huì)引起此共享資源的不一致性,而解決安全問(wèn)題則需要同步鎖的加入,執(zhí)行synchronized部分代碼的時(shí)候必須需要對(duì)象鎖,而一個(gè)對(duì)象只有一個(gè)鎖,只有執(zhí)行完synchronized里面的代碼后釋放鎖,其他線程才可以獲得鎖,那么就保證了同一時(shí)刻只有一個(gè)線程訪問(wèn)synchronized里面的代碼。實(shí)現(xiàn)資源共享的關(guān)鍵是,只有一個(gè)實(shí)例,synchronized使用的是同一把鎖,用實(shí)例的鎖或者定義一個(gè)實(shí)例。這就需要使用實(shí)現(xiàn)Runnable接口的方式,實(shí)現(xiàn)多線程,這樣傳入的是一個(gè)實(shí)例。繼承Thread的方式,傳入的是多個(gè)實(shí)例,每個(gè)實(shí)例都有一個(gè)鎖,那就無(wú)法實(shí)現(xiàn)控制。
以上這篇多線程(多窗口賣(mài)票實(shí)例講解)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot bean查詢(xún)加載順序流程詳解
當(dāng)你在項(xiàng)目啟動(dòng)時(shí)需要提前做一個(gè)業(yè)務(wù)的初始化工作時(shí),或者你正在開(kāi)發(fā)某個(gè)中間件需要完成自動(dòng)裝配時(shí)。你會(huì)聲明自己的Configuration類(lèi),但是可能你面對(duì)的是好幾個(gè)有互相依賴(lài)的Bean2023-03-03
springboot validator枚舉值校驗(yàn)功能實(shí)現(xiàn)
這篇文章主要介紹了springboot validator枚舉值校驗(yàn)功能實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
Delegate IDE build/run actions to maven 配置會(huì)影響程序運(yùn)行嗎?
這篇文章主要介紹了Delegate IDE build/run actions to maven 配置會(huì)影響程序運(yùn)行嗎,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
Java設(shè)計(jì)模式中的建造者(Builder)模式解讀
這篇文章主要介紹了Java設(shè)計(jì)模式中的建造者(Builder)模式解讀, 建造者模式是一種創(chuàng)建對(duì)象的設(shè)計(jì)模式,它通過(guò)將對(duì)象的構(gòu)建過(guò)程分解為多個(gè)步驟,并使用一個(gè)建造者類(lèi)來(lái)封裝這些步驟,從而使得對(duì)象的構(gòu)建過(guò)程更加靈活和可擴(kuò)展,需要的朋友可以參考下2023-10-10
關(guān)于SpringCloud?Ribbon替換輪詢(xún)算法問(wèn)題
Spring?Cloud?Ribbon是基于Netlix?Ribbon實(shí)現(xiàn)的一套客戶(hù)端負(fù)載均衡的工具。接下來(lái)通過(guò)本文給大家介紹SpringCloud?Ribbon替換輪詢(xún)算法問(wèn)題,需要的朋友可以參考下2022-01-01
Java中注解@Async實(shí)現(xiàn)異步及導(dǎo)致失效原因分析
Async注解用于聲明一個(gè)方法是異步的,當(dāng)在方法上加上這個(gè)注解時(shí)將會(huì)在一個(gè)新的線程中執(zhí)行該方法,而不會(huì)阻塞原始線程,這篇文章主要給大家介紹了關(guān)于Java中注解@Async實(shí)現(xiàn)異步及導(dǎo)致失效原因分析的相關(guān)資料,需要的朋友可以參考下2024-07-07
Java基礎(chǔ)知識(shí)精通數(shù)組的內(nèi)存分析
數(shù)組對(duì)于每一門(mén)編程語(yǔ)言來(lái)說(shuō)都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語(yǔ)言對(duì)數(shù)組的實(shí)現(xiàn)及處理也不盡相同。Java?語(yǔ)言中提供的數(shù)組是用來(lái)存儲(chǔ)固定大小的同類(lèi)型元素2022-04-04

