中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站建設(shè)政策自己如何注冊一個網(wǎng)站

網(wǎng)站建設(shè)政策,自己如何注冊一個網(wǎng)站,wordpress 適配 手機(jī),哈鐵工程建設(shè)公司網(wǎng)站文章目錄一.線程安全的概念1.1 線程安全的概念1.2 線程不安全的原因1.3 解決線程不安全二.synchronized-monitor lock(監(jiān)視器鎖)2.1 synchronized的特性(1)互斥(2)刷新內(nèi)存(3)可重入2.2 synchronied使用方法1.直接修飾普通方法:2.修飾靜態(tài)方法:3.修飾代碼塊:三.死鎖3.1死鎖的情…

文章目錄

  • 一.線程安全的概念
    • 1.1 線程安全的概念
    • 1.2 線程不安全的原因
    • 1.3 解決線程不安全
  • 二.synchronized-monitor lock(監(jiān)視器鎖)
    • 2.1 synchronized的特性
      • (1)互斥
      • (2)刷新內(nèi)存
      • (3)可重入
    • 2.2 synchronied使用方法
      • 1.直接修飾普通方法:
      • 2.修飾靜態(tài)方法:
      • 3.修飾代碼塊:
  • 三.死鎖
    • 3.1死鎖的情況
    • 3.2 死鎖的四個必要條件
      • 1.互斥使用
      • 2.不可搶占
      • 3.請求和保持
      • 4.循環(huán)等待
    • 3.3解決死鎖的辦法
  • 四.volatile 關(guān)鍵字
  • 五. wait和notify
    • 5.1 wait()方法
    • 5.2 notify()方法

一.線程安全的概念

先來看一段代碼

class Counter{public int count = 0;public void add(){count++;}}
public class Thread14 {public static void main(String[] args) throws InterruptedException {Counter counter = new Counter();Thread t1  = new Thread(()->{for (int i = 0; i < 50000; i++) {counter.add();}});Thread t2 = new Thread(() ->{for (int i = 0; i < 50000; i++) {counter.add();}});t1.start();t2.start();t1.join();t2.join();System.out.println("count = "+ counter.count);}
}

可以看到結(jié)果是不確定的

在這里插入圖片描述
這里是引用

1.1 線程安全的概念

先來說一下非線程安全的概念:非線程安全主要是指多個線程對同一個對象中的同一個實例變量進(jìn)行操作時會出現(xiàn)值被更改、值不同步的情況,進(jìn)而影響程序的執(zhí)行流程。
線程安全:如果多線程環(huán)境下代碼運(yùn)行的結(jié)果是符合我們預(yù)期的,即在單線程環(huán)境應(yīng)該的結(jié)果,則說這個程序是線程安全的。

1.2 線程不安全的原因

先解釋上述線代碼程不安全的原因:
在這里插入圖片描述

如果兩個線程并發(fā)執(zhí)行count++,此時就相當(dāng)于兩組load add save進(jìn)行執(zhí)行,此時不同的線程調(diào)度順序就可能會產(chǎn)生一些結(jié)果上的差異

由于線程的搶占執(zhí)行,導(dǎo)致當(dāng)前執(zhí)行到任意一個指令,線程都可能bei調(diào)度走,CPU讓別的線程來執(zhí)行
如下圖:
在這里插入圖片描述
導(dǎo)致下面的結(jié)果:
在這里插入圖片描述
線程安全問題的原因:
1.搶占式執(zhí)行,隨機(jī)調(diào)度(根本原因)
2.代碼結(jié)構(gòu):多個線程同時修改同一個變量
3.原子性(操作是非原子性,容易出現(xiàn)問題)
4.內(nèi)存可見性問題(如一個線程讀,一個線程改)
5.指令重排序

1.3 解決線程不安全

從原子性入手,通過加鎖,把非原子的,轉(zhuǎn)成"原子"的
在這里插入圖片描述
加了synchronized之后,進(jìn)入方法就會加鎖,出了方法就會解鎖,如果兩個線程同時嘗試加鎖,此時一個能獲取鎖成功,另一個只能阻塞等待(BLOCKED),一直阻塞到剛才的線程解鎖,當(dāng)前線程才能加鎖成功

二.synchronized-monitor lock(監(jiān)視器鎖)

2.1 synchronized的特性

(1)互斥

  • 進(jìn)入sychronized修飾的代碼塊,相當(dāng)于加鎖
  • 退出sychronizde修飾的代碼塊,相當(dāng)于解鎖

(2)刷新內(nèi)存

synchronized的工作過程:

1.獲得互斥鎖
2.從內(nèi)存拷貝變量的最新副本到工作的內(nèi)存
3.執(zhí)行代碼
4.將更改后的共享變量的值刷新到主內(nèi)存
5.釋放互斥鎖

(3)可重入

synchronized同步塊對同一條線程來說是可重入的,不會出現(xiàn)自己把自己鎖死的問題(自己可以再次獲取自己的內(nèi)部鎖)
理解"把自己鎖死"
一個線程沒有釋放鎖,然后又嘗試再次加鎖
在這里插入圖片描述
按照之前對于鎖的設(shè)定,第二次加鎖的時候,就會阻塞等待,而獲取不到第一次的鎖,就把自己鎖死

2.2 synchronied使用方法

1.直接修飾普通方法:

鎖的SynchronizedDemo1對象

public class SynchronizedDemo1 {public synchronized void methond() {}
}

2.修飾靜態(tài)方法:

鎖SynchronizedDemo2對象

public class SynchronizedDemo2 {public synchronized void methond() {}
}

3.修飾代碼塊:

明確指定鎖哪個對象

public class SychronizedDemo{public void method(){sychronized(this){}}
}

鎖類對象

public class SynchronizedDemo {public void method() {synchronized (SynchronizedDemo.class) {}}
}

三.死鎖

3.1死鎖的情況

1.一個線程,連續(xù)加鎖兩次,如果鎖是不可重入鎖,就會死鎖
2.兩個線程,兩把鎖,t1和t2各自先針對鎖A和鎖B加鎖,在獲取對方的鎖

public class Thread15 {public static void main(String[] args) {Object lock1 = new Object();Object  lock2= new Object();Thread t1 = new Thread(()->{synchronized (lock1){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock2){System.out.println("t1把鎖1和鎖2都獲得了");}}});Thread t2 = new Thread(()->{synchronized (lock2){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock1){System.out.println("t2把鎖1和鎖2都獲得了");}};});t1.start();t2.start();}
}

在這里插入圖片描述
3.多個線程,多把鎖(相當(dāng)于2的一般情況)

3.2 死鎖的四個必要條件

1.互斥使用

線程1拿到了鎖,線程2就須等著

2.不可搶占

線程1拿到鎖A之后,必須是線程1主動釋放

3.請求和保持

線程1拿到鎖A之后,在嘗試獲取鎖B,A這把鎖還是保持的

4.循環(huán)等待

線程1嘗試獲取到鎖A和鎖B,線程2嘗試獲取鎖B和鎖A,線程1在獲取B的時候等待線程2釋放B,同時線程2 在獲取A的時候等待線程1釋放A

3.3解決死鎖的辦法

給鎖編號,然后指定一個固定的順序來加鎖,任意線程加把鎖,都讓線程遵守上述順序,此時循環(huán)等待自然破除

對于synchronied前三個條件都是鎖的基本特性,我們只能對四修改

public class Thread15 {public static void main(String[] args) {Object lock1 = new Object();Object  lock2= new Object();Thread t1 = new Thread(()->{synchronized (lock1){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock2){System.out.println("t1把鎖1和鎖2都獲得了");}}});Thread t2 = new Thread(()->{synchronized (lock1){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock2){System.out.println("t2把鎖1和鎖2都獲得了");}};});t1.start();t2.start();}
}

在這里插入圖片描述

四.volatile 關(guān)鍵字

volatile 和內(nèi)存可見性問題密切相關(guān)

一個線程針對一個變量進(jìn)行讀取操作,同時另一個線程針對這個變量進(jìn)行修改,此時讀取到值,不一定是修改之后的值(歸根結(jié)底是編譯器/jvm在多線程下優(yōu)化時產(chǎn)生了誤判)

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
使用匯編語言解釋
1.load,把內(nèi)存中flag的值,讀取到寄存器
2.cmp把寄存器的值和0進(jìn)行比較,根據(jù)比較結(jié)果,決定下一不執(zhí)行.
由于load執(zhí)行速度太慢(相比于cmp來說),再加上反復(fù)load的結(jié)果都一樣,JVM就不在重復(fù)load判定沒人改flag值,就只讀取一次就好
而給flag加上volatile關(guān)鍵字,告訴編譯器變量是"易變"的,不再進(jìn)行優(yōu)化

class MyCounter{volatile public int flag = 0;
}
public class Thread16 {public static void main(String[] args) {MyCounter myCounter = new MyCounter();Thread t1 = new Thread(() ->{while (myCounter.flag == 0){//循環(huán)體空著}System.out.println("t1循環(huán)結(jié)束");});Thread t2 = new Thread(() ->{Scanner scanner = new Scanner(System.in);System.out.println("請輸入一個整數(shù):");myCounter.flag = scanner.nextInt();});t1.start();t2.start();}
}

結(jié)果:
在這里插入圖片描述

五. wait和notify

wait和notify可以協(xié)調(diào)線程之間的先后順序

完成這個協(xié)調(diào)工作, 主要涉及到三個方法

  • wait() / wait(long timeout): 讓當(dāng)前線程進(jìn)入等待狀態(tài).
  • notify() / notifyAll():喚醒在當(dāng)前對象上等待的線程.

注意: wait, notify, notifyAll 都是 Object 類的方法

5.1 wait()方法

wait的操作
1.先釋放鎖
2.在阻塞等待
3.收到通知之后,重新獲取鎖,并且在獲取鎖后,繼續(xù)往下執(zhí)行

wait操作需要搭配synchorized來使用

public class Thread17 {public static void main(String[] args) throws InterruptedException {Object object = new Object();System.out.println("wait之前");object.wait();System.out.println("wait之后");}
}

無synchorized的情況
在這里插入圖片描述
wait無參數(shù)版本,就是死等
wait帶參數(shù)版本,指定了等待的最大時間

5.2 notify()方法

notify()方法是喚醒等待線程

  • 如果有多個線程等待,則有線程調(diào)度器隨機(jī)挑選出一個呈 wait 狀態(tài)的線程。(并沒有 “先來后到”)

  • 在notify()方法后,當(dāng)前線程不會馬上釋放該對象鎖,要等到執(zhí)行notify()方法的線程將程序執(zhí)行完,也就是退出同步代碼塊之后才會釋放對象鎖。

notfiyAll()方法可以一次喚醒所有的等待線程

http://www.risenshineclean.com/news/10768.html

相關(guān)文章:

  • 國外做行程的網(wǎng)站廣告詞
  • 太湖縣城鄉(xiāng)建設(shè)局網(wǎng)站2023網(wǎng)站推廣入口
  • 如何給網(wǎng)站做宣傳網(wǎng)站注冊信息查詢
  • 外包公司做網(wǎng)站多少seo網(wǎng)絡(luò)推廣技術(shù)員招聘
  • 網(wǎng)站扁平化布局seo快速排名網(wǎng)站優(yōu)化
  • 做旅游網(wǎng)站需要引進(jìn)哪些技術(shù)人才搜索引擎優(yōu)化是什么工作
  • 50m專線做視頻網(wǎng)站無錫網(wǎng)絡(luò)公司
  • 電子商務(wù)網(wǎng)站開發(fā)軟件在線看seo網(wǎng)站
  • WordPress評級評分主題如何做網(wǎng)站seo
  • 手機(jī)怎么做網(wǎng)站免費(fèi)的最佳磁力吧ciliba搜索引擎
  • 499可以做網(wǎng)站百度廣告推廣平臺
  • 記錄網(wǎng)站 自己做自助建站的優(yōu)勢
  • 怎么做網(wǎng)站界面設(shè)計百度愛企查電話人工服務(wù)總部
  • 網(wǎng)站建設(shè)個人網(wǎng)上銀行seo先上排名后收費(fèi)
  • 電子商務(wù)網(wǎng)站建設(shè)的展望參考網(wǎng)是合法網(wǎng)站嗎?
  • 鄭州網(wǎng)站建設(shè)漢獅網(wǎng)絡(luò)營銷方式
  • 手把手教做網(wǎng)站能打開各種網(wǎng)站的瀏覽器
  • python 開發(fā)手機(jī)網(wǎng)站開發(fā)網(wǎng)頁制作軟件下載
  • wordpress jpg https貴州網(wǎng)站seo
  • 用織夢做網(wǎng)站能練技術(shù)嗎seo排名優(yōu)化課程
  • 設(shè)計團(tuán)隊網(wǎng)站新站seo外包
  • 網(wǎng)站顏色搭配哪里有免費(fèi)的網(wǎng)站推廣軟件
  • 長春做高端網(wǎng)站公司網(wǎng)頁百度
  • 百度推廣做網(wǎng)站百度快照不更新怎么辦
  • 愛網(wǎng)站網(wǎng)站查詢汽車營銷策劃方案ppt
  • 網(wǎng)站建設(shè) 站內(nèi)搜索網(wǎng)頁設(shè)計模板圖片
  • 手機(jī)端網(wǎng)站開發(fā)各地疫情最新消息
  • 什么網(wǎng)站專門做自由行的游戲推廣員怎么做
  • 怎么查詢網(wǎng)站是否被收錄百度網(wǎng)址大全設(shè)為主頁
  • 江蘇省徐州市建設(shè)銀行網(wǎng)站a站