Javaマルチスレッドの主従設計モード-yellowcong


HadoopやRedisなどのクラスタでは,主従の概念があり,要求の配布と結果の統計を制御し,ノードから真のデータ処理操作に用いる主従の概念がある.マルチスレッドでは、1つの大きなタスクを複数の小さなタスクに分割し、サブノードに処理することができます.この設計モードでは、要求されたタスクを格納するための原子クラスConcurrentLinkedQueueと、各ノードで取得した結果を収集するためのConcurrentHashMapを使用する必要があります.このようなロックされていない設計モードでは、データの統一問題を解決するために原子クラスのオブジェクトを使用する必要があります.
マルチスレッド開発では,ロック方式ではなく原子系を多く用いて問題を解決する必要があり,ロック方式の方が効率が相対的に低く,notifyやwait方式はLock系のロックに及ばないため,開発では原子系に使用できるものは,できるだけ原子系で完成する.
タスク・オブジェクト
任意のオブジェクトは、単純なjava beanにすぎず、複雑な処理はありません.このケースでは、ワークスレッドを介して複数のタスクに分割された加算演算が設計されています.
package com.yellowcong.work;

/**
 *     :2017 10 6  
* :yellowcong
* : */
public class Task { private String name; private String id; private Integer price; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } }

Masterクラス
プライマリ・オブジェクトには、3つの重要なオブジェクト1、ConcurrentLinkedQueueが必要です.タスク・キューを収集し、コミットされたすべてのタスクをこのキューに配置します.HashMap Masterが管理するWorkオブジェクト(タスク処理ノード、マスターノードが何人の子弟の完了人物を管理できるかを判断する)を維持し、タスクを追加した後、このオブジェクトのスレッドを遍歴し、ワークタスク3、ConcurrentHashMapを起動してワークノードごとの処理の結果を収集し、マスターノードで統計処理を行う
package com.yellowcong.work;

import java.security.KeyStore.Entry;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 *     :2017 10 6  
* :yellowcong
* : */
public class Master { //1. private ConcurrentLinkedQueue tasks = new ConcurrentLinkedQueue(); //2.master Works private HashMap works = new HashMap(); //3. private ConcurrentHashMap results = new ConcurrentHashMap(); //4、 public Master(Work work,int count) { // work result work.setResults(results); work.setTasks(tasks); // Work HashMap for(int i=0;i//key , val works.put(String.valueOf(i),new Thread(work)); } } //5、 public void submit(Task task){ this.tasks.add(task); } //6、 public void execute(){ for(Map.Entry entry :works.entrySet()){ // entry.getValue().start(); } } //7. public boolean isComplite(){ for(Map.Entry entry :works.entrySet()){ // , if(entry.getValue().getState() != Thread.State.TERMINATED){ return false; } } return true; } //8. public long getResult(){ long data = 0l; for(Map.Entry entry :results.entrySet()){ data += Long.parseLong(String.valueOf(entry.getValue().toString())); } return data; } }

Workクラス
このクラスはRunableインタフェースを実現し,この中にはConcurrentHashMap ConcurrentLinkedQueueという2つの集合オブジェクトがあり,Masterによって伝達され,タスクを取得し,タスク処理の結果を格納することを目的としている.
package com.yellowcong.work;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 *     :2017 10 6  
* :yellowcong
* :Master ,Master Work */
public class Work implements Runnable { private ConcurrentHashMap results; private ConcurrentLinkedQueue tasks; public void setResults(ConcurrentHashMap results) { this.results = results; } public void setTasks(ConcurrentLinkedQueue tasks) { this.tasks = tasks; } public void run() { while(true){ // if(tasks.isEmpty()){ break; } // Task task = this.tasks.poll(); Object result = haddle(task); // this.results.put(task.getId(), result); } } /** * * :2017 10 6
* :yellowcong
* : * @param task * @return */
private Object haddle(Task task) { try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return task.getPrice(); } }

テストクラス
テストクラスでは,10個のワークオブジェクトを起動してタスク全体を完了し,スレッド数が増えると全体的なロック時間が減少する.
package com.yellowcong.work;

import java.util.Random;

/**
 *     :2017 10 6  
* :yellowcong
* : */
public class MainTest { public static void main(String[] args) { System.out.println(Thread.activeCount()); // Master master = new Master(new Work(), 10); Random rand = new Random(); for(int i=0;i<100;i++){ Task task = new Task(); task.setId(String.valueOf(i)); task.setName(" "+i); task.setPrice(rand.nextInt(1000)); // master.submit(task); } // long start = System.currentTimeMillis(); master.execute(); // while(true){ if(master.isComplite()){ long result = master.getResult(); long end = System.currentTimeMillis(); System.out.println(" "+result+", "+Long.toString(end-start)); break; } } } }