Javaプログラミングマルチスレッドの共有データコードの詳細解


本論文では主にスレッド共有データに関する知識をまとめ、主に2つの側面を含む。一つはスレッド内でデータをどう共有するか、各スレッドのデータが交差しないことを保証する。一つは複数のスレッド間でデータをどう共有するか、データの整合性を保証することです。
スレッド範囲でデータを共有する
自分で実現すると、Mapを定義し、スレッドをキーとし、データを値とし、テーブルの各々はスレッドごとに準備されたデータであり、このようにスレッド内のデータは一致している。

package com.iot.thread;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
 * Created by brian on 2016/2/4.
 */
public class ThreadScopeShareData {
	//       ,         
	private static Map<Thread,Integer> threadData = new HashMap<>();
	public static void main(String[] args) {
		for (int i=0;i<2;i++){
			new Thread(
			          new Runnable() {
				@Override
				        public void run() {
					int data = new Random().nextint();
					threadData.put(Thread.currentThread(),data);
					System.out.println(Thread.currentThread()+" put data:"+data);
					new A().get();
					new B().get();
				}
			}
			).start();
		}
	}
	static class A{
		public void get(){
			int data = threadData.get(Thread.currentThread());
			System.out.println("A from "+Thread.currentThread()+" get data "+data);
		}
	}
	static class B{
		public void get(){
			int data = threadData.get(Thread.currentThread());
			System.out.println("B from "+Thread.currentThread()+" get data "+data);
		}
	}
}
上記のコードは時々異常を報告します。
Exception in thread“Thread-0”java.lang.Null PointerException
at comp.iot.thread.ThreadScompeShardataドルA.get(ThreadScompeShare Data.java:29)
at comp.iot.thread.ThreadScompeShardataドル1.run(ThreadScompeShare Data.java:21)
at java.lang.Thread.run(Thread.java:745)
具体的な原因はまだ分かりません。
ThreadLocal類
API:
java.lang:Class ThreadLocal
  • 単変数
  • ThreadLocalタイプのオブジェクトを上のMapの代わりに使えばいいです。
  • マルチ変数
  • オブジェクトを指定して複数の変数をカプセル化し、オブジェクト全体をThreadLocalに格納します。
    多変数の場合、ThreadLocal類をデータクラスの内部に置くことが望ましいです。データ類は一例モードを採用します。このように、新規作成の対象と取得の対象はより便利になります。同時にパッケージ性がより強いです。
    サンプルコード:
    
    package com.iot.thread;
    import java.util.Random;
    /**
     * Created by brian on 2016/2/4.
     */
    public class ThreadLocalTest {
    	private static ThreadLocal<Integer> threadInger = new ThreadLocal<>();
    	public static void main(String[] args) {
    		for (int i=0;i<2;i++){
    			new Thread(new Runnable() {
    				@Override
    				        public void run() {
    					int data = new Random().nextint(100);
    					threadInger.set(data);
    					System.out.println(Thread.currentThread()+" put data:"+data);
    					MyThreadScopeData.getThreadInstance().setName(Thread.currentThread().toString());
    					MyThreadScopeData.getThreadInstance().setAge(data%10);
    					new A().get();
    					new B().get();
    				}
    			}
    			).start();
    		}
    	}
    	static class A{
    		public void get(){
    			int data = threadInger.get();
    			System.out.println("A from "+Thread.currentThread()+" get data "+data);
    			MyThreadScopeData myThreadScopeData = MyThreadScopeData.getThreadInstance();
    			System.out.println("A from "+myThreadScopeData);
    		}
    	}
    	static class B{
    		public void get(){
    			int data = threadInger.get();
    			System.out.println("B from "+Thread.currentThread()+" get data "+data);
    			MyThreadScopeData myThreadScopeData = MyThreadScopeData.getThreadInstance();
    			System.out.println("B from "+myThreadScopeData);
    		}
    	}
    }
    /**
     *             
     *     ,  ThreadLocal    
     */
    class MyThreadScopeData{
    	private MyThreadScopeData(){
    	}
    	private static ThreadLocal<MyThreadScopeData> data = new ThreadLocal<>();
    	public static MyThreadScopeData getThreadInstance(){
    		MyThreadScopeData instance = data.get();
    		if(instance == null){
    			instance = new MyThreadScopeData();
    			data.set(instance);
    		}
    		return instance;
    	}
    	private String name;
    	private int age;
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	@Override
    	  public String toString() {
    		String reVal = super.toString()+"-{name,age}"+":{"+getName()+","+getAge()+"}";
    		return reVal;
    	}
    }
    マルチスレッドアクセス共有データ
    いくつかの方法
  • スレッド実行コードは同じで、同じRunnableオブジェクトを使用して、Runnableオブジェクトには共有データ
  • があります。
  • スレッド実行コードが異なり、共有データを別のオブジェクトにカプセル化し(操作データの方法もこのオブジェクトで完了)、このオブジェクトを各Runnableオブジェクトに1つずつ渡す。本質:データを共有する対象はパラメータとしてRunnableオブジェクトに入る。
  • スレッド実行コードが異なり、Runnableオブジェクトをあるクラスの内部クラスとして共有するデータは、この外部クラスのメンバー変数(データを操作する方法は外部クラス)として使用されます。本質:異なる内部クラスの共有外部クラスのデータ]
  • は、2つの方法に関連して、共有データを別のオブジェクトにカプセル化する(オペレーティングデータの方法もこのオブジェクトで完了する)。このオブジェクトは、この外部クラスのメンバ変数として、Runnableオブジェクトを内部クラスとする。
  • 最後の方法の例:
    5つのスレッドが設計されており、このうち3つのスレッドはjに対して1ずつ増加し、他の2つのスレッドはjに対して1回ずつ減少する。
    
    package com.iot.thread;
    /**
     * Created by brian on 2016/2/4.
     */
    public class MutiThreadShareData {
    	private static MutiShareData mutiShareData = new MutiShareData();
    	public static void main(String[] args) {
    		for (int i=0;i<3;i++){
    			new Thread(
    			          new Runnable() {
    				@Override
    				            public void run() {
    					System.out.println(Thread.currentThread()+":{j from "+ mutiShareData.getJ()+" + to: "+mutiShareData.increment()+"}");
    				}
    			}
    			).start();
    		}
    		for (int i=0;i<2;i++){
    			new Thread(
    			          new Runnable() {
    				@Override
    				            public void run() {
    					System.out.println(Thread.currentThread()+":{j from "+ mutiShareData.getJ()+" - to: "+mutiShareData.decrement()+"}");
    				}
    			}
    			).start();
    		}
    	}
    }
    /**
     *              (              )
     */
    class MutiShareData{
    	private int j = 0;
    	public synchronized int increment(){
    		return ++j;
    	}
    	public synchronized int decrement(){
    		return --j;
    	}
    	public synchronized int getJ() {
    		return j;
    	}
    	public synchronized void setJ(int j) {
    		this.j = j;
    	}
    }
    締め括りをつける
    以上がJavaプログラミングマルチスレッドの共有データコードについての詳細な内容です。興味のある方は引き続き当駅の他のテーマを参照してください。友達のサポートに感謝します。