多線程訪問共用對象和數據的方式

来源:http://www.cnblogs.com/lcngu/archive/2016/02/17/5150024.html
-Advertisement-
Play Games

在多線程訪問共用對象和數據時候大致可以分為兩大類。 1:如果每個線程執行的代碼相同,可以使用同一個runnable對象,這個runnable對象中有那個共用對象。如:買票系統。 1 public class MulteThreadlShareData { 2 public static void m


在多線程訪問共用對象和數據時候大致可以分為兩大類。

1:如果每個線程執行的代碼相同,可以使用同一個runnable對象,這個runnable對象中有那個共用對象。如:買票系統。

 1 public class MulteThreadlShareData {
 2     public static void main(String[] args) {
 3         ShareData shareData = new ShareData();
 4         new Thread(shareData).start();
 5         new Thread(shareData).start();
 6     }
 7     
 8     static class ShareData implements Runnable{
 9         int count = 100;
10         @Override
11         public void run() {
12             while(count>0){
13                 decrease();
14             }
15         }
16         public synchronized void decrease(){
17             count--;
18             System.out.println(Thread.currentThread().getName()+"this count: "+count);
19         }
20         
21     }
22 }

2:如果每個線程執行的代碼不相同,就要用不同的runnable對象了。這種方式又有兩種來實現這些runnable對象之間的數據共用。

  •   將共用數據封裝在另一個對象中,然後將這個對象逐一傳遞給各個runnable對象中。每個線程共用數據的操作方法也分配到了這個對象身上去完成,這樣容易實現針對該數據進行共用數據的互斥和通信。代碼實現如下:
     1 public class MulteThreadlShareData2 {
     2     public static void main(String[] args) {
     3         final ShareData shareData = new ShareData();
     4         new Thread(new Decrease(shareData)).start();
     5         new Thread(new Increment(shareData)).start();
     6     }
     7     
     8     static class Decrease implements Runnable{
     9         private ShareData shareData;
    10         public Decrease(ShareData shareData){
    11             this.shareData=shareData;
    12         }
    13         @Override
    14         public void run() {
    15             shareData.decrease();
    16         }
    17         
    18     }
    19     static class Increment implements Runnable{
    20         private ShareData shareData;
    21         public Increment(ShareData shareData){
    22             this.shareData=shareData;
    23         }
    24         @Override
    25         public void run() {
    26             shareData.increment();
    27         }
    28         
    29     }
    30     
    31     static class ShareData{
    32         int count = 100;
    33         public synchronized void decrease(){
    34             count--;
    35             System.out.println(Thread.currentThread().getName()+"decrease this count: "+count);
    36         }
    37         public synchronized void increment(){
    38             count++;
    39             System.out.println(Thread.currentThread().getName()+"increment this count: "+count);
    40         }
    41     }
    42 }

     

  •   將這些runnable對象作為某個類的內部類,共用數據作為這個外部類的成員變數,每個線程對共用數據的操作也分配到外部類,以便實現對共用數據進行的各個操作進行互斥和通信,作為內部類的各個runnable對象調用外部類的這些方法。
     1 public class MulteThreadlShareData3 {
     2     static int count = 100;
     3     public static void main(String[] args) {
     4         new Thread(new Decrease()).start();
     5         new Thread(new Increment()).start();
     6         
     7     }
     8     public synchronized static void decrease(){
     9         count--;
    10         System.out.println(Thread.currentThread().getName()+"decrease this count: "+count);
    11     }
    12     public synchronized static void increment(){
    13         count++;
    14         System.out.println(Thread.currentThread().getName()+"increment this count: "+count);
    15     }
    16     static class Decrease implements Runnable{
    17         @Override
    18         public void run() {
    19             decrease();
    20         }
    21         
    22     }
    23     static class Increment implements Runnable{
    24         @Override
    25         public void run() {
    26             increment();
    27         }
    28         
    29     }
    30 }

     

  •   上面兩種方式的結合:將共用數據封裝到另一個對象中,各個線程對共用數據操作的方法也分配到那個對象上去完成,對象作為外部類的成員變數或方法的局部變數,每個runnable對象作為外部類中的成員內部類或局部內部類。
     1 public class MulteThreadlShareData1 {
     2     public static void main(String[] args) {
     3         final ShareData shareData = new ShareData();
     4         new Thread(new Runnable() {
     5             @Override
     6             public void run() {
     7                 while(true){
     8                     shareData.decrease();
     9                 }    
    10             }
    11         }).start();
    12         new Thread(new Runnable() {
    13             @Override
    14             public void run() {
    15                 while(true){
    16                     shareData.increment();
    17                 }
    18                 
    19             }
    20         }).start();
    21     }
    22     
    23     static class ShareData{
    24         int count = 100;
    25         public synchronized void decrease(){
    26             count--;
    27             System.out.println(Thread.currentThread().getName()+"this count: "+count);
    28         }
    29         public synchronized void increment(){
    30             count++;
    31             System.out.println(Thread.currentThread().getName()+"this count: "+count);
    32         }
    33     }
    34 }

     

總之:要同步和互斥的幾段代碼最好放在幾個獨立的方法中,這些方法在放在同一個類中,這樣容易實現他們之間的同步互斥和通信。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 出處:http://www.cnblogs.com/_popc 引言:當前能看到很多互聯網網站中有關web前端優化都採用js合併壓縮的方式輸出。樓主找了幾個地址參考 地址1、地址2 那麼下麵就開始瞭如何實現。 1.既然需要將js合併壓縮輸出那麼就先需要構造一個如上鏈接所示的那樣的鏈接地址。 @usi
  • 【問】 假設有一個類庫文件LibraryA,其中有一個ClassA,該類的AssemblyName為“LibraryA”(編譯後的文件是LibraryA.dll)。另外有一個LibraryB.dll類庫文件,其中AssemblyName和其命名空間一樣,並且其引用LibraryA.dll。它們代碼如
  • 一、前言 在關於技術上的學習,常常有這樣那樣的計劃,而最終一個都沒有真正的落實。零散的學習,終究需要系統總結,才能使自己有所沉澱。從畢業至今,我一直在忙碌,為公司付出自己的很多很多,卻只不過是一隻只會拉磨的驢: 1、只做一樣的事情(聽從領導的安排且做好,從不質疑,殊不知領導的規劃能力很弱。) 2、只
  • 1.ViewData:可存放任意類型數據,使用時需要轉換,ViewData[“Info”]="hello",適合傳遞單個數據; 2.ViewBag:是對ViewData的封裝,可讀取ViewData保存的數據,反之亦然,ViewBag.stu=objStudent; 3.TempData:可跨視圖,
  • 1.視圖引擎:把視圖解析成瀏覽器可執行的html代碼 2.aspx視圖: <%=表達式%>: <% C#代碼段 %>: 3.razor視圖: @(表達式):@ViewData["name"],如果@後跟常量,必須用括弧括起來:@(“hello”) @{C#代碼段}:@{ if(a>b) { retu
  • 對象為null時調用給對象的屬性或方法 “未將對象引用到實例”是很多像我一樣的初學者經常遇到的一個問題,常常令人煩惱不已,那麼這個問題是怎麼發生的呢?先給大家看一張圖,我們從這張圖入手來分析這個錯誤造成的原因。 可能很多人看到這樣的代碼會覺得可笑:”能寫出這樣的代碼,看來此人的智商已“超越”人類的範...
  • 先鋪墊一些基礎知識 在 .net 4.5中出現了 Async Await關鍵字,配合之前版本的Task 來使得開發非同步程式更為簡單易控。 在使用它們之前 我們先關心下 為什麼要使用它們。好比 一個人做幾件事,那他得一件一件的做完,而如果添加幾個人手一起幫著做 很顯然任務會更快的做好。這就是並行的粗淺
  • 創建: 使用setcookie( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $ht
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...