日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

线程、同步

發(fā)布時間:2025/3/20 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程、同步 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

目錄

一、多線程

1.多線程的原理

2.線程類Thread的介紹

3.創(chuàng)建線程的兩種方式

4.兩種創(chuàng)建線程方式的區(qū)別

二、線程安全

1.線程安全問題出現(xiàn)的原因

2.線程同步

(1)同步代碼塊

(2)同步方法

(3)Lock鎖

三、線程的狀態(tài)

1.線程的六種狀態(tài)

四、代碼練習(xí)

1.賣包子案例

2.過山洞案例


一、多線程

1.多線程的原理

同一時間內(nèi),CPU只能處理1條線程,只有1條線程在工作(執(zhí)行);多線程并發(fā)(同時)執(zhí)行,其實是CPU快速地在多條線程之間調(diào)度(切換)。如果CPU調(diào)度線程的時間足夠快,就造成了多線程并發(fā)執(zhí)行的假象。

程序啟動運行main時候,java虛擬機啟動一個進程,其中有一個主線程(main方法調(diào)用時候被創(chuàng)建)。隨著調(diào)用Thread對象的start方法,另外一個新的線程也啟動了,這樣,整個應(yīng)用就在多線程下運行。

2.線程類Thread的介紹

構(gòu)造方法:

public Thread() :分配一個新的線程對象。

public Thread(String name) :分配一個指定名字的新的線程對象。

public Thread(Runnable target) :分配一個帶有指定目標(biāo)新的線程對象。

public Thread(Runnable target,String name) :分配一個指定目標(biāo)新的線程對象并指定名字。

常用方法:

public String getName() :獲取當(dāng)前線程名稱。

public void start() :導(dǎo)致此線程開始執(zhí)行; Java虛擬機調(diào)用此線程的run方法。

public void run() :此線程要執(zhí)行的任務(wù)在此處定義代碼。

public static void sleep(long millis) :使當(dāng)前正在執(zhí)行的線程以指定的毫秒數(shù)暫停(暫時停止執(zhí)行)。

public static Thread currentThread() :返回對當(dāng)前正在執(zhí)行的線程對象的引用。

3.創(chuàng)建線程的兩種方式

方式一:

? 描述:

將一個類聲明為一個Thread的子類。

這個子類應(yīng)該重寫run類的方法,然后可以分配并啟動子類的實例

步驟:

a.創(chuàng)建子類 繼承 Threand (子類也是一個代表線程的類)

b.子類中重寫run方法(編寫任務(wù)代碼的地方)

c.創(chuàng)建子類對象(創(chuàng)建一個線程對象)

d.啟動線程,調(diào)用線程對象.start();

注意:

啟動線程必須調(diào)用start,而不是調(diào)用run

方式二:

描述:

實現(xiàn)Runnable接口方式

步驟:

a.定義Runnable接口的實現(xiàn)類,并重寫該接口的run()方法

b.用public Thread(Runnable target)的構(gòu)造方法創(chuàng)建Thread對象

c.啟動線程,調(diào)用線程對象.start();

4.兩種創(chuàng)建線程方式的區(qū)別

實現(xiàn)Runnable接口比繼承Thread類所具有的優(yōu)勢:

(1)可以避免java中的單繼承的局限性。

(2)實現(xiàn)解耦操作,任務(wù)可以被多個線程共享,任務(wù)和線程獨立。

(3)線程池只能放入實現(xiàn)Runable或Callable類線程,不能直接放入繼承Thread的類。

5.使用匿名內(nèi)部類創(chuàng)建線程

使用匿名內(nèi)部類的方式實現(xiàn)Runnable接口,重新Runnable接口中的run方法

二、線程安全

1.線程安全問題出現(xiàn)的原因

當(dāng)有多個線程在同時運行,這些線程同時運行一段代碼(同一段任務(wù)代碼,同一個run方法),操作同一個共享數(shù)據(jù)時,這時候可能就會出現(xiàn)線程的安全問題,即線程不安全的。

2.線程同步

使線程按照一定的先后次序進行運行

(1)同步代碼塊

synchronized(同步鎖){

需要同步操作的代碼

}

對象的同步鎖只是一個概念,可以想象為在對象上標(biāo)記了一個鎖.

①鎖對象 可以是任意類型。

②多個線程對象 要使用同一把鎖。

(2)同步方法

public synchronized void method(){

可能會產(chǎn)生線程安全問題的代碼

}

對于非static方法,同步鎖就是this。

對于static方法,我們使用當(dāng)前方法所在類的字節(jié)碼對象(類名.class)。

(3)Lock鎖

java.util.concurrent.locks.Lock 機制提供了比synchronized代碼塊和synchronized方法更廣泛的鎖定操作,同步代碼塊/同步方法具有的功能Lock都有,除此之外更強大,更體現(xiàn)面向?qū)ο蟆?/p>

Lock鎖也稱同步鎖,加鎖與釋放鎖方法化了,如下:

public void lock() :加同步鎖。

public void unlock()?:釋放同步鎖。

?

?????Lock l = ...;

?????l.lock();

?????try {

?????????// access the resource protected by this lock

?????} finally {

?????????l.unlock();

?????}

?

三、線程的狀態(tài)

1.線程的六種狀態(tài)

(1)新建狀態(tài)(new)

線程剛被創(chuàng)建,但是并未啟動。還沒調(diào)用start方法。

(2)可運行狀態(tài)(Runnable)

線程可以在java虛擬機中運行的狀態(tài),可能正在運行自己代碼,也可能沒有,這取決于操作系統(tǒng)處理器。

(3)受阻塞狀態(tài)(Blocked)

當(dāng)一個線程試圖獲取一個對象鎖,而該對象鎖被其他的線程持有,則該線程進入Blocked狀態(tài);當(dāng)該線程持有鎖時,該線程將變成Runnable狀態(tài)。

(4)限時等待狀態(tài)(TimeWaiting)

同waiting狀態(tài),有幾個方法有超時參數(shù),調(diào)用他們將進入Timed Waiting狀態(tài)。這一狀態(tài)將一直保持到超時期滿或者接收到喚醒通知。帶有超時參數(shù)的常用方法有Thread.sleep()、鎖對象.wait()。

(5)無限等待狀態(tài)(Waiting)

一個線程在等待另一個線程執(zhí)行一個(喚醒)動作時,該線程進入Waiting狀態(tài)。進入這個狀態(tài)后是不能自動喚醒的,必須等待另一個線程調(diào)用notify或者notifyAll方法才能夠喚醒。

(6)消亡狀態(tài)(Teminated)

因為run方法正常退出而死亡,或者因為沒有捕獲的異常終止了run方法而死亡。

四、代碼練習(xí)

1.賣包子案例

包子鋪賣包子,有包子時則不生產(chǎn),買家在沒包子時不消費包子,有包子時消費包子。

public class BaoZi {boolean flag=false;//判斷包子有沒有 } public class BaoZiTest {public static void main(String[] args) {BaoZi bz = new BaoZi();Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {while (true) {//如果包子沒有了,調(diào)用wait()方法進入waiting狀態(tài)synchronized (bz) {if (bz.flag == false) {try {bz.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("吃貨醒來了");System.out.println("吃貨吃包子");System.out.println("吃貨吃完了...");//包子吃完了,使flag=false并喚醒做包子線程bz.flag = false;bz.notify();}}}});t1.start();Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {while (true) {synchronized (bz) {//如果還有包子,調(diào)用wait()方法進入waiting狀態(tài)if (bz.flag == true) {try {bz.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("包子鋪發(fā)現(xiàn)沒包子了");System.out.println("包子鋪做包子");System.out.println("包子已經(jīng)上架了...");//包子做出來了,使flag=true并喚醒吃包子線程bz.flag = true;bz.notify();}}}});t2.start();System.out.println("hello");} }

2.過山洞案例

請按要求編寫多線程應(yīng)用程序,模擬多個人通過一個山洞: 1.這個山洞每次只能通過一個人,每個人通過山洞的時間為5秒; 2.隨機生成10個人,同時準(zhǔn)備過此山洞,并且定義一個變量用于記錄通過隧道的人數(shù)。 顯示每次通過山洞人的姓名,和通過順序; import java.util.ArrayList; import java.util.Collections; import java.util.Random;public class GuoShanDong {ArrayList<String> names = new ArrayList<>();int a=1;public GuoShanDong() {Collections.addAll(names, "路飛", "索隆", "娜美", "喬巴", "香吉士","烏索普", "弗蘭奇", "甚平", "布魯克", "羅賓");}public synchronized void guoShanDong() {Random r = new Random();if (names.size() > 0) {int i = r.nextInt(names.size());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println((a++)+"---"+Thread.currentThread().getName() + "---" + names.remove(i) + "正在通過山洞...");}} } public class Test09 {static int a = 1;public static void main(String[] args) {GuoShanDong gsd = new GuoShanDong();int i = 0;new Thread(new Runnable() {@Overridepublic void run() {while (gsd.a <= 10) {gsd.guoShanDong();}}}).start();new Thread(new Runnable() {@Overridepublic void run() {while (gsd.a <= 10) {gsd.guoShanDong();}}}).start();} }

?

總結(jié)

以上是生活随笔為你收集整理的线程、同步的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。