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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java线程锁机制_多线程之锁机制

發布時間:2025/3/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java线程锁机制_多线程之锁机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

在Java并發編程實戰,會經常遇到多個線程訪問同一個資源的情況,這個時候就需要維護數據的一致性,否則會出現各種數據錯誤,其中一種同步方式就是利用Synchronized關鍵字執行鎖機制,鎖機制是先給共享資源上鎖,只有拿到鎖的線程才可以訪問共享資源,其他線程進入等待狀態。下面將以實例代碼講解一下

一、wait()、nofity()、nofityAll()講解

示例代碼

package thread;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.concurrent.TimeUnit;/**

* Created by StoneGeek on 2018/5/19.

* 博客地址:http://www.cnblogs.com/sxkgeek* 當線程執行wait()時,會把當前的鎖釋放,然后讓出CPU,進入等待狀態。

* 當線程執行notify()/notifyAll()方法時,會喚醒一個處于等待狀態該對象鎖的線程,然后繼續往下執行,直到執行完退出對象鎖鎖住的區域(synchronized修飾的代碼塊)后再釋放鎖

* 個人認為synachronized(){}執行完后會釋放鎖*/

public classWaitNotify {static boolean flag = true;static Object lock = newObject();public static voidmain(String[] args) throws Exception {

Thread waitThread= new Thread(new Wait(), "WaitThread");

waitThread.start();

TimeUnit.SECONDS.sleep(1);

Thread notifyThread= new Thread(new Notify(), "NotifyThread");

notifyThread.start();

}static classWait implements Runnable {public voidrun() {//加鎖,擁有lock的Monitor

synchronized (lock) {//當條件不滿足時,繼續wait,同時釋放了lock的鎖

while(flag) {

System.out.println(Thread.currentThread().getName()+ "flag is true. wait@"

+ new SimpleDateFormat("HH:mm:ss")

.format(newDate()));try{lock.wait();

System.out.println("此處繼續執行"+Thread.currentThread().getName());//flag=true;

} catch(InterruptedException e) {

e.printStackTrace();

}

}//條件滿足時,完成工作

System.out.println(Thread.currentThread().getName()+ "flag is false. running@"

+ new SimpleDateFormat("HH:mm:ss").format(newDate()));

}

synchronized (lock){

System.out.println(Thread.currentThread().getName()+"執行結束");

}

}

}//wait()會立刻釋放synchronized(obj)中的obj鎖,以便其他線程可以執行obj.notify()//但是notify()不會立刻立刻釋放sycronized(obj)中的obj鎖,必須要等notify()所在線程執行完synchronized(obj)塊中的所有代碼才會釋放這把鎖.//yield(),sleep()不會釋放鎖

static classNotify implements Runnable {public voidrun() {//加鎖,擁有lock的Monitor

synchronized (lock) {//獲取lock的鎖,然后進行通知,通知時不會釋放lock的鎖,//直到當前線程釋放了lock后,WaitThread才能從wait方法中返回

System.out.println(Thread.currentThread().getName()+ "hold lock. notify @"

+ new SimpleDateFormat("HH:mm:ss").format(newDate()));lock.notifyAll();

flag= false;

}//再次加鎖

synchronized (lock) {

System.out.println(Thread.currentThread().getName()+ "hold lock again. sleep@"

+ new SimpleDateFormat("HH:mm:ss").format(newDate()));

}

synchronized (lock){

System.out.println(Thread.currentThread().getName()+"執行結束");

}

}

}

}

執行結果如下

1 WaitThread flag is true. wait@ 20:50:392 NotifyThread holdlock. notify @ 20:50:403 NotifyThread holdlock again. sleep@ 20:50:404 NotifyThread執行結束

5 此處繼續執行WaitThread

6 WaitThread flagis false. running@ 20:50:407 WaitThread執行結束

解釋:

首先創建一個lock對象,然后給這個lock上鎖來對多個進程同步,flag是一個標志,用來跳出while循環。

當線程執行wait()時,會把當前的鎖釋放,然后讓出CPU,進入等待狀態。

此時輪到notifythread線程,并且執行notifyAll(),這個意思是能夠喚醒所有正在等待這個lock對象的monitor的線程,但是

必須要等notify()所在線程執行完synchronized(obj)塊中的所有代碼才會釋放這把鎖,

此時接著waitthread被喚醒,繼續執行while循環,執行完之后,由于flag在notifythread中置為false,所以跳出while循環(如果在實例代碼的wail()后加flag=true結果是截然不同,由于notirythread進程執行完,此時會一直陷入wait,大家可以試試),

執行console打印5 6 7

notify()與notifyAll()的區別

notify()方法能夠喚醒一個正在等待該對象的monitor的線程,當有多個線程都在等待該對象

的monitor的話,則只能喚醒其中一個線程

而調用notifyAll()方法能夠喚醒所有正在等待這個對象的monitor的線程

當時的疑惑

(1)既然notify或者notifyAll需要執行完synchronized塊中的內容,那么他還有什么存在的價值的

后來執行完之后,才發現要是沒有這個方法,那么synchronized塊執行完之后,waitthread還是在等待狀態,無法被喚醒。

(2)wait被notify喚醒之后,是接著執行,所以console打印5,并不是從頭執行(如果在實例代碼的wail()后加flag=true結果是截然不同,由于notirythread進程執行完,waitthread進程重新執行wait方法,此時會一直陷入wait,無其他進程喚醒此進程)

二、sychronized(object)跟sychroized(this)的區別、使用場景

(1)首先創建一個objeck,然后sychronzied(object){}

static Object lock = newObject();

synchronized (lock) {}

這種情況是當多個線程執行不同的代碼但是希望分別執行,不同時進行,當然可以加wait、notify來進行鎖機制同步

(2)sychronized(this)

synchronized (lock) {}

這種情況是多個線程執行相同的代碼,但是希望分別執行.

三、wait()/wait(long)和sleep(long)方法的區別

將示例代碼中的lock.wait()改為Thread.sleep(1000),console打印

WaitThread flag is true. wait@ 21:29:49此處繼續執行WaitThread

WaitThread flagis true. wait@ 21:29:50此處繼續執行WaitThread

WaitThread flagis true. wait@ 21:29:51此處繼續執行WaitThread

WaitThread flagis true. wait@ 21:29:52此處繼續執行WaitThread

由此說明sleep并沒有釋放鎖。

區別:

1、Sleep(long)是Thread的方法,而wait()/wait(long)是Object的方法

2、Sleep(long)可以放在sychnoized塊內也可以不放在里面,但是wait()/wait(long)必須放在語句塊內

3、Sleep(long)不釋放鎖,只是讓當前線程暫停一段時間,而wait()/wait(long)是釋放鎖

4、wait()將當前線程放到阻塞隊列,只有調用notify()/notifyAll()方法后,才將其從阻塞隊列中移動到就緒隊列,等待被CPU調度,而wait(long)方法執行后就是放到阻塞隊列,等待時間到期或者被wait()/wait(long)喚醒后就可以放到就緒隊列被CPU調度

目前還有一個疑惑,就是線程中的run方法有兩個同樣的synchroized(lock),是不是跟一個synchroized(lock)效果是一樣的,目前就運行結果來看是這樣子的!

總結

以上是生活随笔為你收集整理的java线程锁机制_多线程之锁机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。