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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

多线程——多线程同步的三种实现方法

發布時間:2024/3/26 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程——多线程同步的三种实现方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

當使用多線程訪問同一個資源的時候,非常容易出現線程安全的問題(例如,當多個線程同時對一個數據進行修改的時候,會導致某些線程對數據的修改丟失)。

因此,需要采用同步機制來解決這種問題。而Java主要提供了三種實現同步機制的方法。今天我們就來認識一下~~

一、synchronized關鍵字

在Java語言中,每個對象都有一個對象鎖與之相關聯,該鎖表明對象在任何時候只允許被一個線程鎖擁有,當一個線程調用對象的一段synchronized代碼時,需要先獲取這個鎖,然后去執行相應的代碼,執行結束之后,釋放鎖。

而synchronized關鍵字主要有兩種用法:synchronized方法synchronized塊。此外,這個關鍵字還可以作用于靜態方法、類或者某個實例,但這都對程序的效率有很大的影響

1.synchronized方法。在方法的聲明前主要有synchronized關鍵字,示例如下:

public?synchronized?void?mutiThreadAccess();

只要把多個線程對類需要被同步的資源的操作放到mutiThreadAccess()方法中,就能保證這個方法在同一時刻只能被同一個線程訪問,從而保證了多線程訪問的安全性。然而,當一個方法的方法體規模非常大時,把該方法聲明為synchronized會大大影響程序的執行效率。為了提高程序的效率,Java提供了synchronized塊。

2.synchronized塊

synchronized塊既可以把任意的代碼段聲明為synchronized,也可以指定上鎖的對象,有非常高的靈活性。其用法如下:

synchronized(syncObject){//訪問synchObject的代碼}

二、wait()方法與notify()方法

當使用synchronized來修飾某個共享資源時,如果線程A1在執行synchronized代碼,另一個線程A2也要同時執行同一個對象的同一synchronized代碼時,線程A2將要等到線程A1執行完成之后,才能繼續執行。在這種情況下可以使用wait()方法和notify()方法。

在synchronized代碼被執行期間,線程可以調用對象的wait()方法,釋放對象鎖,進入等待狀態,并且可以調用notify()方法或者notifyAll()方法通知正在等待的其他線程。notify()方法僅喚醒一個線程(即等待隊列中的第一個線程),并允許它去獲得鎖,notifyAll()方法喚醒所有等待這個對象的線程并允許他們去獲得鎖,但并不是讓所有喚醒線程都去獲取到鎖,而是讓他們去競爭。

三、Lock

JDK5新增加了Lock接口以及它的一個實現類ReentrantLock(重入鎖),Lock也可以用來實現多線程的同步。具體而言,它提供了如下一些方法來實現多線程的同步:

1.lock()。

這個方法以阻塞的方式獲取鎖,也就是說,如果獲取到鎖了,立即返回;如果別的線程持有鎖,當前線程就等待,知道獲取到鎖之后返回。

2.tryLock()。

這個方法與lock()方法不同,它以非阻塞的方式來獲取鎖。此外,它只是常識性地去獲取一下鎖,如果獲取到了鎖,立即返回true,否則立即返回false。

3.tryLock(long?timeout,TimeUnit unit)

如果獲取到鎖,立即返回true,否則會等待參數給定的時間單元,在等待的過程中,如果獲取到了鎖,就返回true,如果等待超時則返回false。

4.lockInterruptibly()

如果獲取了鎖,立即返回;如果沒有獲取到鎖,當前線程處于休眠狀態,直到獲取到鎖,或者當前線程被別的線程中斷(會受到InterruptedException異常)。它與lock()方法最大的區別在于如果lock()方法獲取不到鎖就會一直處于阻塞狀態,而且還會忽略interrupt()方法。

示例如下:

package javatest;import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class LockTest {public static void main(String[] args)throws InterruptedException {// TODO Auto-generated method stubfinal Lock lock=new ReentrantLock();lock.lock();Thread t1=new Thread(new Runnable() {public void run() {try {lock.lockInterruptibly();}catch(InterruptedException e){System.out.println("interrupted");}}});t1.start();t1.interrupt();Thread.sleep(1);} }

運行結果如下:?

如果把lock.lockInterruptibly()替換為lock.lock(),編譯器將會提示lock.lock()catch代碼塊無效,這是因為lock.lock()不會拋出異常,由此可見lock()方法會忽略interrupt()引發的異常。

?

好啦,以上就是實現Java多線程同步的三種方法的相關總結,如果大家有什么更具體的發現或者發現文中有描述錯誤的地方,歡迎留言評論,我們一起學習呀~~

?

Biu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~pia!

總結

以上是生活随笔為你收集整理的多线程——多线程同步的三种实现方法的全部內容,希望文章能夠幫你解決所遇到的問題。

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