JavaConcurrentLinkedQueue佇列執行緒安全操作

開開心心過發表於2017-03-25


Java ConcurrentLinkedQueue佇列執行緒安全操作

程式碼示例:

package async;

import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 
 * 執行緒安全佇列Queue實現計算科學古老的執行緒同步問題:生產者-消費者模型
 * 
 * @author phil
 *
 */
public class Demo {
	public static void main(String[] args) {
		// 執行緒操作安全佇列,裝載資料
		Queue<String> queue = new ConcurrentLinkedQueue<String>();

		// 消費者執行緒:不斷的消費佇列中的資料
		// 該執行緒不停的從佇列中取出佇列中最頭部的資料
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					// 從佇列的頭部取出並刪除該條資料
					String s = queue.poll();

					if (s != null) {
						System.out.println(System.currentTimeMillis() + "取出資料:" + s);
					}
				}
			}

		}).start();

		// 生產者執行緒A:不斷的生產單個資料並裝入佇列中
		// 該執行緒模擬不停的在佇列中裝入一個資料
		new Thread(new Runnable() {
			private int count = 0;
			private int number = 0;

			@Override
			public void run() {
				while (true) {
					number = count++;
					System.out.println("裝載資料:" + number);
					queue.add(String.valueOf(number));

					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}

		}).start();

		// 生產者執行緒B:不斷的生產批量資料並裝入佇列中
		// 該執行緒模擬不停的在佇列中裝入一批資料
		new Thread(new Runnable() {
			private List<String> lists = new ArrayList<String>();
			private int count = 0;

			@Override
			public void run() {
				while (true) {
					// 一批資料的數量,不定長
					count = (int) (Math.random() * 5);
					for (int i = 0; i < count; i++) {
						lists.add("批量資料-" + i + "," + Math.random());
					}

					queue.addAll(lists);
					lists.clear();

					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}

		}).start();
	}
}

程式碼執行結果:

裝載資料:0
1490417519703取出資料:0
1490417519705取出資料:批量資料-0,0.9045746291285363
裝載資料:1
1490417520703取出資料:1
1490417520705取出資料:批量資料-0,0.9378737341890285
1490417520705取出資料:批量資料-1,0.5609780480099475
1490417520705取出資料:批量資料-2,0.27383078038481046
1490417520705取出資料:批量資料-3,0.6824300990854635
裝載資料:2
1490417521704取出資料:2
1490417521706取出資料:批量資料-0,0.23916865770830298
裝載資料:3
1490417522704取出資料:3
1490417522706取出資料:批量資料-0,0.4169859285695523
1490417522706取出資料:批量資料-1,0.6667611178989155
1490417522706取出資料:批量資料-2,0.9026516620769446
1490417522706取出資料:批量資料-3,0.3491566771349188
裝載資料:4
1490417523705取出資料:4
1490417523707取出資料:批量資料-0,0.5634243124726268
1490417523707取出資料:批量資料-1,0.4021826644433847
裝載資料:5
1490417524705取出資料:5
1490417524707取出資料:批量資料-0,0.9431588628811881
1490417524707取出資料:批量資料-1,0.8762171226841987
1490417524707取出資料:批量資料-2,0.0470837112538508
裝載資料:6
1490417525705取出資料:6
1490417525707取出資料:批量資料-0,0.31099249499423265
1490417525707取出資料:批量資料-1,0.7660770869693369
1490417525707取出資料:批量資料-2,0.3209338524956993
1490417525707取出資料:批量資料-3,0.2525376039263991
裝載資料:7
1490417526706取出資料:7
1490417526708取出資料:批量資料-0,0.6369286896471094

致謝:
馮貴兵對本文有重大貢獻!

附錄:
1,《Java同步機制:synchronized,wait,notify》連結地址:http://blog.csdn.net/zhangphil/article/details/43800949
2,《Java執行緒同步:生產者-消費者 模型(程式碼示例)》連結地址:http://blog.csdn.net/zhangphil/article/details/43800967


相關文章