1. 程式人生 > >多執行緒訪問共享資料(1)

多執行緒訪問共享資料(1)

多執行緒訪問共享資料解決方案:

一,什麼是多執行緒

 執行緒是程式中一個單一的順序控制流程.在單個程式中同時執行多個執行緒完成不同的工作,稱為多執行緒.

 所有的執行緒雖然在微觀上是序列執行的,但是在巨集觀上你完全可以認為它們在並行執行

二,多執行緒訪問共享資料解決方案

1,如果每個執行緒執行的程式碼相同,可以使用同一個Runnable物件,這個Runnable物件中有那個共享資料。例如:賣票系統。

2,如果每個執行緒執行的程式碼不同,這個時候需要用不同的Runnable物件,有如下方式來實現這些Runnable物件之間的資料共享:

將共享資料封裝在另外一個物件中,然後將這個物件逐一傳遞給各個

Runnable物件。每個執行緒對共享資料的操作方法也分配到那個物件身上去完成,這樣容易實現針對該資料進行的各個操作的互斥和通訊。

將這些Runnable物件作為某一個類中的內部類共享資料作為這個外部類中的成員變數,每個執行緒對共享資料的操作方法也分配給外部類,以便實現對共享資料進行的各種操作的互斥和通訊,作為內部類的各個Runable物件呼叫外部類的這些方法。

上面兩種方式的組合:將共享資料封裝在另外一個物件中,每個執行緒對共享資料的操作方法也分配到那個物件身上去完成,物件作為這個外部類中的成員變數或方法中的區域性變數,每個執行緒的Runnable物件作為外部類中的成員內部類或區域性內部類。

總之,要同步互斥的幾段程式碼最好是分別放在幾個獨立的方法中這些方法再放在同一個類中,這樣比較容易實現他們之間的同步互斥和通訊。

一個外部類A中有兩個內部類,這兩個內部類BC如何共享資料?

——BC都操作外部類A的同一個成員變數。所以,兩個Runnable物件要共享同一份資料,可以把兩個Runnable作為外部類的內部類,把共享資料作為外部類的成員變數。

三,例子:

1,如果每個執行緒執行的程式碼相同,可以使用同一個Runnable物件,這個Runnable物件中有那個共享資料。例如:賣票系統。

程式碼解釋:開啟三個執行緒,同時訪問共享資料count,均對其進行--操作。實現思路:由於三個執行緒執行的程式碼相同(對共享資料的操作相同),所以使用同一個Runnable(如下程式碼:類ShareData1實現Runnable介面),該Runnable物件中封裝了共享資料count,即對共享資料count的操作。

package com.tgb.thread07;

	/**
	 * 多執行緒訪問共享物件和資料之——模擬賣票系統
	 * 方案:由於買票時每個執行緒執行的程式碼相同(均是在現有票數上--),因此 可以使用同一個Runnable物件,
	 *     這個Runnable物件中有那個共享資料。例如:賣票系統。
	 * 
	 * @author hanxuemin
	 * @date 2015年7月30日10:06:35
	 *
	 */
	public class MultiThreadShareData {
	
		public static void main(String[] args) {
	
			ShareData1 data1 = new ShareData1();
			/**
			 * 開啟三個執行緒,賣票,訪問共享資料
			 */
			new Thread(data1).start();
			new Thread(data1).start();
			new Thread(data1).start();
		}
	}
	
	/**
	 * 包含共享資料的Runnable實現類ShareData1
	 * 
	 * @author hanxuemin
	 * 
	 */
	class ShareData1 implements Runnable {
	
		private int count = 100; // 票數總共100張(共享資料)
	
		public void run() {
			while (count > 0) {
				count--; // 票數-1
				System.out.println(Thread.currentThread().getName() + "買票後,票總數為:" + count);
			}
		}
	
	}

2,如果每個執行緒執行的程式碼不同,這個時候需要用不同的Runnable物件,有如下方式來實現這些Runnable物件之間的資料共享:

   方式一:將共享資料封裝在另外一個物件中,然後將這個物件逐一傳遞給各個Runnable物件。每個執行緒對共享資料的操作方法也分配到那個物件身上去完成,這樣容易實現針對該資料進行的各個操作的互斥和通訊。

Demo:設計4個執行緒,其中兩個執行緒每次對j增加1,另外兩個執行緒對j每次減少1。寫出程式。

程式碼解釋:(1)共享資料為j,兩個執行緒對其++,兩個執行緒對其--,因此執行的程式碼不同,因此需要不同的Runnable物件;(2)看題得知4個執行緒對共享資料共兩種操作,所以建立兩個不同的Runnable實現類——MyRunnable1、MyRunnable2;(3)在建立類ShareData2,將共享資料封裝在該類中,同時封裝了每個執行緒對共享資料的操作方法;(4)將ShareData2物件逐一傳遞給每個Runnable物件。

package com.tgb.thread07;

/**
 * 多執行緒訪問共享物件和資料之——每個執行緒執行的程式碼不同
 * 
 * 方案:如果每個執行緒執行的程式碼不同,這個時候需要用不同的Runnable物件, 有如下三種方式來實現這些Runnable物件之間的資料共享:
 * 方案一:將共享資料封裝在另外一個物件中,然後將這個物件逐一傳遞給各個Runnable物件。
 * 每個執行緒對共享資料的操作方法也分配到那個物件身上去完成,這樣容易實現針對該資料進行的各個操作的互斥和通訊。
 * 
 * 該程式實現Demo:設計4個執行緒,其中兩個執行緒每次對j增加1,另外兩個執行緒對j每次減少1。寫出程式。
 * 分析:(1)對共享資料分別有兩個操作:<a>對共享資料j進行++;<b>對共享資料j進行--; ——所以
 * 需要建立兩個Runnable物件(分別對j進行++ 和 --)
 * 
 * @author hanxuemin
 * @date 2015年7月30日10:06:35
 *
 */
public class MultiThreadShareData02 {

	public static void main(String[] args) {

		final ShareData2 data2 = new ShareData2();// 建立ShareData2例項物件(該物件中封裝了共享資料,和每個執行緒對共享資料的操作方法)
		for (int i = 0; i < 2; i++) {
			/**
			 * 建立兩個Runnable物件,將封裝了共享資料的data2物件逐一傳遞給這兩個Runnable物件
			 */
			MyRunnable1 myRunnable1 = new MyRunnable1(data2);
			MyRunnable2 myRunnable2 = new MyRunnable2(data2);
			/**
			 * 啟動兩個執行緒,這兩個執行緒使用兩個不同的Runnable
			 */
			new Thread(myRunnable1).start();
			new Thread(myRunnable2).start();
		}
	}
}

/**
 * MyRunnable1實現Runnable介面
 * 
 * @author hanxuemin
 *
 */
class MyRunnable1 implements Runnable {
	private ShareData2 data2;

	public MyRunnable1(ShareData2 data2) {
		this.data2 = data2;
	}

	@Override
	public void run() {
		data2.increment(); // 呼叫++方法
	}

}

/**
 * MyRunnable2類實現Runnable介面
 * 
 * @author hanxuemin
 *
 */
class MyRunnable2 implements Runnable {

	private ShareData2 data2;

	public MyRunnable2(ShareData2 data2) {
		this.data2 = data2;
	}

	@Override
	public void run() {
		data2.decrement(); // 呼叫--方法

	}
}

/**
 * 封裝了共享資料的類ShareData2。同時,該類封裝了每個執行緒對共享資料的操作方法
 * 
 * @author hanxuemin
 * 
 */
class ShareData2 {

	private int j = 100; // 共享資料j

	/**
	 * 對j進行++的方法
	 */
	public synchronized void increment() {
		j++;
		System.out.println("++方法:" + Thread.currentThread().getName()
				+ "操作共享資料後,當前共享資料的值為" + j);
	}

	/**
	 * 對j進行--的方法
	 */
	public synchronized void decrement() {
		j--;
		System.out.println("--方法" + Thread.currentThread().getName()
				+ "操作共享資料後,當前共享資料的值為" + j);
	}
}

四,總結

不同是情況使用不同的解決方案。
另外兩種方式,見下一篇部落格

相關推薦

執行訪問共享資料1

多執行緒訪問共享資料解決方案: 一,什麼是多執行緒  執行緒是程式中一個單一的順序控制流程.在單個程式中同時執行多個執行緒完成不同的工作,稱為多執行緒.  所有的執行緒雖然在微觀上是序列執行的,但是在巨集觀上你完全可以認為它們在並行執行 二,多執行緒訪問共享資料解決方

java併發-執行執行之間共享資料6

多執行緒共享資料的方式: 1,如果每個執行緒執行的程式碼相同,可以使用同一個Runnable物件,這個Runnable物件中有那個共享資料,例如,賣票系統就可以這麼做。 2,如果每個執行緒執行的程式碼不同,這時候需要用不同的Runnable物件,例如,設計4個執行緒

我的android執行程式設計之路1之經驗詳解,原始碼分析

寫在伊始 android開發這麼久了,對於多執行緒這塊一直處於似懂非懂的神奇狀態,今天總結出來,分享一下,希望大家多多指正。共同交流,懇望得到您的建議。 本文簡介 本文會基於自己在開發中對於執行緒這塊的實際使用,大概從執行緒程序的概念,執行緒的建立(T

.NET執行技術詳解1

預設情況下,C# 程式具有一個執行緒。此執行緒執行程式中以Main方法開始和結束的程式碼。Main直接或間接執行的每一個命令都由預設執行緒(或主執行緒)執行,當Main返回時此執行緒也將終止。不過,可以建立輔助執行緒,以便與主執行緒一起並行執行程式碼。這些執行緒通常稱為“輔

執行3-執行訪問共享物件和資料的方式

在多執行緒(2)-ThreadLocal,我們討論了執行緒範圍內的資料共享,本篇文章我們討論執行緒之間即多執行緒訪問共享物件和資料的方式 一:Java5之前給共享資料加上鎖synchronized,上程式碼 public class MultiThreadShareDat

執行訪問共享物件和資料

1、如果每個執行緒執行的程式碼相同,可以使用同一個runnable物件,這個runnable物件中有那個共享資料。例如賣票系統。 2、如果每個執行緒執行的程式碼不同,這時候需要用不同的runnable物件,有如下兩種方式來實現這些runnable物件之間的資料共

執行訪問共享物件和資料的方式

如果每個執行緒執行的程式碼相同,可以使用同一個Runnable物件,這個Runnable物件中有那個共享資料,比如:在之前提到的賣票程式中,是兩個執行緒,同時減去100張票,也就是說這兩個執行緒的操作

python中執行共享資料,通過queue來實現,內有生產者消費者經典模型的示例程式碼

queue:佇列,即先進先出,它有以下幾個方法: 1.判斷佇列的大小:size() 2.向佇列中新增:put() 3.向佇列中取出:get() 4.如果佇列規定了長度,用來判斷是否滿了:full() import threading,time import queu

執行訪問共享記憶體的不加鎖實現方式

http://blog.csdn.net/alane1986/article/details/6887359 多執行緒訪問共享記憶體,為了實現同步,常採用加鎖的方式。 那麼,如何採用不加鎖的方式來達到執行緒同步的目的呢? 思路: 儲存兩塊共享記憶體,一塊用於讀

詳解 Qt 執行共享資料使用signal/slot傳遞資料執行間傳遞訊號會立刻返回,但也可通過connect改變

相關文章使用共享記憶體。即使用一個兩個執行緒都能夠共享的變數(如全域性變數),這樣兩個執行緒都能夠訪問和修改該變數,從而達到共享資料的目的。Qt 執行緒間共享資料是本文介紹的內容,多的不說,先來啃內容。Qt執行緒間共享資料主要有兩種方式:使用共享記憶體。即使用一個兩個執行緒都

個人珍藏的80道執行併發面試題1-10答案解析

前言 個人珍藏的80道Java多執行緒/併發經典面試題,因為篇幅太長,現在先給出1-10的答案解析哈,後面一起完善,並且上傳github哈~ ❝ https://github.com/whx123/JavaHome ❞ 「公眾號:撿田螺的小男孩」 1. synchronized的實現原理以及鎖優化? sync

PYTHON——執行:訊號量Semaphore

  訊號量也是一把鎖,用來控制執行緒併發數的。   BoundedSemaphore或Semaphore管理一個內建的計數 器,每當呼叫acquire()時-1,呼叫release()時+1。       計數器不能小於0,當計數器為 0時,acquire()將阻塞執行緒至同

PYTHON——執行:條件變數Condition

  條件變數(Condition)也是一把鎖,除了同步鎖的作用外,還具有線上程間通訊的功能。   有一類執行緒需要滿足條件之後才能夠繼續執行,Python提供了threading.Condition 物件用於條件變數執行緒的支援,它除了能提供RLock()或Lock()的方法外,還提供了 wait()、no

C++執行中的future期望

Providers std::promise 和std::future配合使用,給std::future傳遞期望值,下面是最簡單的一個用法: #include <iostream> #include <functional> #include <

執行斷點續傳

一、 學習內容 1、 多檔案下載列表的顯示 2、 啟動多個執行緒分段下載 二、 多執行緒下載原理簡介 假設要分3個執行緒下載一個100位元組的檔案:從頭到尾,每個執行緒下載一段 三、 學習點 1、 Adapter的getCount() 2、 A

執行斷點續傳

一、 學習內容 1、 基本UI定義 2、 資料庫的操作 3、 Service的啟動 4、 Activity給service傳遞引數 5、 使用廣播回傳資料到Activity 6、 執行緒和Handler 7、 網路操作:檔案的寫入,網路往本地磁碟寫入 二、 網路下

Java執行之基礎篇

上一篇介紹了Java多執行緒的基礎概念和synchronized關鍵字,這篇繼續介紹Java多執行緒的其他關鍵字和重要的方法。 一、volatile關鍵字 1.1 Java記憶體模型

Java執行之基礎篇

一、併發和並行 1.1 概念 1.2 比較 1.3 程序和執行緒 二、基礎概念 2.1 執

Java執行程式設計學習總結

  (尊重勞動成果,轉載請註明出處:https://blog.csdn.net/qq_25827845/article/details/84894463冷血之心的部落格) 系列文章: Java多執行緒程式設計學習總結(一) Java多執行緒程式設計學習總結(二) 前

Android執行-----併發和同步volatile

volatile是Java提供的一種輕量級的同步機制,在併發程式設計中,它也扮演著比較重要的角色。同synchronized相比(synchronized通常稱為重量級鎖),volatile更輕量級,相比使用synchronized所帶來的龐大開銷,倘若能恰當的合理的使用volatile,自然是好事