多線程之間的通信(等待喚醒機制、Lock 及其它線程的方法)

一、多線程之間的通信。

    就是多個線程在操作同一份數據, 但是操作的方法不同。

    如: 對于同一個存儲塊,其中有兩個存儲位:name ? sex, 現有兩個線程,一個向其中存放數據,一個打印其中的數據。

    為了解決上述問題中的安全問題(在存放線程進行存放操作的時候, 打印線程不能對共有數據進行操作),所以應當對兩個線程
? ? ? ?操作共有數據的代碼部分進行同步(使用synchronized(),來進行同步, 注意 :使用同一個對象作為同步鎖。

二、等待喚醒機制。

    在上述案例實現過后運行,會發現:打印結果順序并不是按照存放順序進行的, 所以在此處就引入了等待喚醒機制。

        解釋:就是在一個線程進行了規定操作后,就進入等待狀態(wait()), 等待其他線程執行完他們的指定代碼過后 再將其喚醒(notify())。
     ? ? 在有多個線程進行等待時, 如果需要,可以使用 notifyAll()來喚醒所有的等待線程。

    所使用的方法(關鍵字):
          對象名.wait(); 在其他線程調用此對象的 notify() 方法或 notifyAll() 方法前,導致當前線程等待。
          對象名.notify(); 喚醒在此對象監視器上等待的單個線程。
          對象名.notifyAll();喚醒在此對象監視器上等待的所有線程。


    
        注意:以上方法(關鍵字),都必須使用在同步中,因為其需要對持有該對象監視器所有權(鎖)的線程進行操作。
      所以必須使用在同步中,因為只有同步中的線程才具有該對象監視器的所有權(鎖),

        wait()和sleep()一樣,都會拋出 InterruptedException 異常。

        而且,以上方法都定義在類:Object中

            是因為,這些方法在操作同步中的線程的時候,都必須標示其所操作線程所持有的鎖(被該鎖的對象調用),
          而只有同一個對象監視器下(同一個鎖上的)的被等待線程,可以被持有該鎖的線程喚醒,(無法喚醒不同鎖上的線程)
            即: 等待和喚醒的必須是同一個對象的監視器下(同一個鎖上)的線程。
          而鎖可以是任意已近確定的對象, 能被任意對象調用的方法應當定義在 Object類中。


      監視器(鎖): 同一個對象的監視器下(同一個鎖上)的線程,一次只能執行一個:就是擁有監視器所有權(持有鎖)的那一個線程。


三、接口Lock和 接口Condition

    注:在使用Lock 與Condition 時,必須引入其工具包:import java.util.concurrent.locks.*

             在jdk1.5以上,為了解決多個線程同時在對一份共享數據進行不同操作時出現的安全問題(要么陷入所有線程同時等待的狀態、

          要么每次喚醒所有等待線程的問題),
              其為我們提供了新的 鎖工具: Lock來替換 synchronized , 由 Lock對象所創建的綁定于該Lock對象的 condition對象

          ??替換了object類中的wait,notify操作。


    1、Lock接口, 已知實現該接口的類: ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock

      1)、 ReentrantLock(大體功能與 synchronized相當,不過可以綁定多個condition)


            構造方法:ReentrantLock() 創建一個 ReentrantLock 的實例。
                 ReentrantLock(boolean fair) 創建一個具有給定公平策略的 ReentrantLock

            常用方法: void lock() :獲取一個鎖。
                 ?void unlock() :釋放該鎖。
                 ?Condition newCondition() 返回用來與此 Lock 實例一起使用的 Condition 實例。




    2、Contition接口, 已知實現類:AbstractQueuedLongSynchronizer.ConditionObject, AbstractQueuedSynchronizer.ConditionObject(暫時不學習)

            常用方法:void await() 造成當前線程在接到信號或被中斷之前一直處于等待狀態。
                 void signal() 喚醒一個等待線程。
                 void signalAll() 喚醒所有等待線程。


        常見代碼示例:
          class BoundedBuffer {
            final Lock lock = new ReentrantLock(); //創建一個Lock的子類對象 lock
            final Condition notFull = lock.newCondition(); //調用lock的newCondition方法,創建一個condition子類對象 notFull
            final Condition notEmpty = lock.newCondition(); //調用lock的newCondition方法,創建一個condition子類對象 notEmpty

            public void put(Object x) throws InterruptedException { //
                lock.lock(); //獲取鎖
                try {
                    while (判斷語句)
                      notFull.await(); //判斷成功,線程等待于notFull下。

                    操作代碼

                    notEmpty.signal(); //喚醒notEmpty下的等待線程。
                } finally { //保證其后語句執行。
                     lock.unlock(); //釋放鎖。
                }
            }

            public Object take() throws InterruptedException {
                lock.lock();
                try {
                  while ()
                    notEmpty.await();
                  操作代碼
                  notFull.signal();

                } finally {
                      lock.unlock();
                }
            }
          }



四、停止線程

      注:在舊版本的jdk中存在stop方法,但是在新版本中。此方法被過時。

      線程停止的原理: 當 run方法中的代碼執行完畢過后,就自動停止該線程。

          1、當線程中是循環代碼的時候, 只要控制住循環結束,就能夠結束該線程。

              特殊情況:當線程中有wait()語句或者await()等語句時,會使得線程處于凍結狀態, 讓控制循環結束的代碼或者標記無法執行或讀取,

            那么線程就不會結束。

              當所有線程都陷入凍結,沒有指定方法解除凍結時,就需要我們強制清除凍結狀態,這樣就可以操作標記使循環結束。

              Thread類中提供了這一方法: Interrupt()方法,(等待型語句本身會有一個InterrptedException異常的判斷,

                      只要被Interrupt方法打斷凍結,就會拋出這一異常, 我們就可以在異常處理語句中建立循環結束的標記)。



五、守護線程

    Thread類中有一個方法,調用該方法并傳入 true ,能將該線程定義為 守護線程(后臺線程),
        該方法是: void setDaemon(boolean on) 將該線程標記為守護線程或用戶線程。(調用時應當傳入true)。

      注意: 1、將該線程標記為守護線程或用戶線程。當正在運行的線程都是守護線程時,Java 虛擬機退出。
        (就是說,后臺線程依賴于前臺線程)

         ?2、該方法必須在啟動線程前調用。

        示例: Thread t = new Thread();
            t.setDaemon(true);
            t.start();
          此時的線程 t 為守護線程。


六、Join方法。

    vpi解釋:void join() 等待該線程終止。

    在線程A執行的時候,碰到了B線程.join方法時,A線程就會等待,等B線程執行完,才繼續執行。
    (當在調用join方法時傳入參數: long millis 時,表示 A線程等待B線程執行時間最長為millis毫秒。)

      join可以用來臨時加入線程執行。

轉載于:https://www.cnblogs.com/soficircle/p/6649272.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/393329.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/393329.shtml
英文地址,請注明出處:http://en.pswp.cn/news/393329.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux iptables 配置詳解

一、配置一個filter表的防火墻 1. 查看本機關于 iptables 的設置情況 # iptables -L -n Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) …

06 Nginx

1.檢查linux上是否通過yum安裝了nginx rpm -qi nginx2.解決安裝nginx所依賴包 yum install gcc patch libffi-devel python-devel zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel ope…

java編寫安卓程序代碼,安卓:從Android的Java源代碼code創建UML

i am looking for a program that can create automatically an Uml from my Java-Android source code.I have tested ArgoUml, but it does not support Android.Have any one a suggestion?Thanks!解決方案I can second what Tom Morris wrote in the comment above. Even …

leetcode1052. 愛生氣的書店老板(滑動窗口)

今天,書店老板有一家店打算試營業 customers.length 分鐘。每分鐘都有一些顧客(customers[i])會進入書店,所有這些顧客都會在那一分鐘結束后離開。 在某些時候,書店老板會生氣。 如果書店老板在第 i 分鐘生氣&#xf…

amazon alexa_在Amazon Alexa上推出freeCodeCamp編碼瑣事測驗

amazon alexaNow you can learn coding concepts hands-free using an Amazon Echo.現在,您可以使用Amazon Echo免提學習編碼概念。 freeCodeCamp.org contributor David Jolliffe created a quiz game with questions on JavaScript, CSS, networking, and comput…

第一類第二類丟失更新

第一類丟失更新 A事務撤銷時,把已經提交的B事務的更新數據覆蓋了。這種錯誤可能造成很嚴重的問題,通過下面的賬戶取款轉賬就可以看出來: 時間 取款事務A 轉賬事務B T1 開始事務 T2 開始事務 T3 查詢賬戶余額為1000元 …

oracle數據字典表與視圖

oracle數據字典表與視圖 數據字典是數據的數據,也就是元數據。描述了數據庫的物理與邏輯存儲與相應的信息。模式中對象的定義信息,安全信息,完整性約束信息,和部分的性能監控信息等。數據字典表 與視圖存儲在system表空間中的。有…

團隊作業——項目Alpha版本發布

---恢復內容開始--- https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/homework/3329 <作業要求的鏈接> Gorious Computer <寫上團隊名稱> 發布項目α版本&#xff0c;對項目…

java臟字過濾_臟字過濾

1.[文件]SensitiveWordFilter.java ~ 7KB下載(141)package com.forgov.sharpc.infrastruture.util;import static java.util.Collections.sort;import java.util.ArrayList;import java.util.Collection;import java.util.Comparator;import java.util.HashSet;import java.uti…

react中使用構建緩存_完整的React課程:如何使用React構建聊天室應用

react中使用構建緩存In this video course, youll learn React by building a chat room app.在本視頻課程中&#xff0c;您將通過構建聊天室應用程序來學習React。 By the end of the video, youll have a solid understanding of React.js and have your very own chat room…

leetcode1509. 三次操作后最大值與最小值的最小差

給你一個數組 nums &#xff0c;每次操作你可以選擇 nums 中的任意一個元素并將它改成任意值。 請你返回三次操作后&#xff0c; nums 中最大值與最小值的差的最小值。 示例 1&#xff1a; 輸入&#xff1a;nums [5,3,2,4] 輸出&#xff1a;0 解釋&#xff1a;將數組 [5,3,…

MySQL異步復制

準備&#xff1a;主備庫版本一致&#xff0c;正常安裝軟件。 1、主庫上設置一個復制使用的賬戶&#xff1a; mysql> grant replication slave on *.* to rep1192.168.100.136 identified by dbking; Query OK, 0 rows affected (0.18 sec) mysql> select user,host,passw…

開源一個爬取redmine數據的測試報告系統

背景 軟件測試的最后有一道比較繁瑣的工作&#xff0c;就是編寫測試報告。手寫測試報告在數據統計和分析上面要耗費比較大的事件和精力。之前工作室使用mantis管理bug缺陷。公司有內部有個系統&#xff0c;可以直接從mantis上面獲取數據并進行統計&#xff0c;生成一份測試報告…

java cxf 雙向通訊_CXF 在spring boot 2 發布多個服務

0. 問題來源之前配置cxf服務端都是在spring 3以下&#xff0c;后來使用spring mvc 還都是基于xml的配置文件模式&#xff0c;在springboot模式下&#xff0c;實現起來更為簡單了。此次記錄下spring boot 2下的實現方式。1. 準備工作項目中&#xff0c;直接拉入spring boot cxf相…

小程序 堅屏_如何構建堅如磐石的應用程序

小程序 堅屏不同的應用程序設計選項概述 (An overview of different app design options) When we design software, we constantly think about error cases. Errors have a huge impact on the way we design and architecture a solution. So much so, in fact, that there …

C# 分層

三層架構分為&#xff1a;表現層&#xff08;UI&#xff09;、業務邏輯層&#xff08;BLL&#xff09;、數據訪問層&#xff08;DAL&#xff09;再加上實體類庫&#xff08;Model&#xff09; 轉載請注明出自朱朱家園http://blog.csdn.net/zhgl7688 1、實體類庫&#xff08;Mod…

leetcode1177. 構建回文串檢測(前綴和)

給你一個字符串 s&#xff0c;請你對 s 的子串進行檢測。 每次檢測&#xff0c;待檢子串都可以表示為 queries[i] [left, right, k]。我們可以 重新排列 子串 s[left], …, s[right]&#xff0c;并從中選擇 最多 k 項替換成任何小寫英文字母。 如果在上述檢測過程中&#xf…

java界面化二叉排序樹_層次序創建二叉樹(圖形界面和控制臺輸入實現)

1 2018.11.72 XT34 /**5 * 功能&#xff1a;構造二叉樹6 * 說明&#xff1a;7 * 1.主函數輸入模式有兩種&#xff0c;BT參數 true 圖形界面&#xff0c;false 控制臺輸入8 * 2.構造樹是按層次遍歷結果輸入的 如&#xff1a;ABCDE*F**GH9 */1011 import javax.swing.*;12 import…

web開發環境_Web開發人員的開發環境

web開發環境With all the tools and programs available, it can be challenging to figure out the best way to set up your development environment on your computer.使用所有可用的工具和程序&#xff0c;尋找在計算機上設置開發環境的最佳方法可能是一項挑戰。 In this…

使用.net Stopwatch class 來分析你的代碼

當我們在調試&#xff0c;優化我們的代碼的時候&#xff0c;想知道某段代碼的真正的執行時間&#xff0c;或者我們懷疑某段代碼&#xff0c;或是某幾段代碼執行比較慢&#xff0c; 需要得到具體的某段代碼的具體執行時間的時候。有一個很好用的類Stopwatch。 Stopwatch 類在 Sy…