스 레 드 범위 내 공유 데이터 ThreadLocal 분석 및 상세 설명

7402 단어 다 중 스 레 드
자바 스 레 드 범위 내의 데이터 공유 메커니즘,해결 해 야 할 문 제 는?  : 여러 업무 모듈 이 같은 static 변 수 를 대상 으로 하 는 작업 은 서로 다른 스 레 드 에서 각 모듈 이 자신 이 대응 하 는 변수 대상 을 조작 하도록 해 야 합 니 다.
실례  A  B 두 종 류 는 같은 static 변수 data 를 조작 해 야 합 니 다.
초기 코드 는 다음 과 같 을 수 있 습 니 다.

  package threadLocal;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 *           
 * @author jingfn
 *
 */
public class ThreadScopeShareDate {
	private static int data ;
	public static void main(String[] args) {
		for(int i=0;i<2;i++)
		new Thread(new Runnable(){
			public  void run(){
					data = new Random().nextInt();
					System.out.println(Thread.currentThread().getName()+"--put data "+data);
					new A().get();
					new B().get();
				}
		}).start();
	}

	static class A{
		private void get(){
			System.out.println("A--get data from "+Thread.currentThread().getName()+" of "+data);
		}
	}
	static class B{
		private void get(){
			System.out.println("B--get data from "+Thread.currentThread().getName()+" of "+data);
		}
	}
}


실행 결과:

  Thread-0--put data 350455289
Thread-1--put data -1313940209
A--get data from Thread-0 of -1313940209
A--get data from Thread-1 of -1313940209
B--get data from Thread-1 of -1313940209
B--get data from Thread-0 of -1313940209

분석 결 과 를 보면 스 레 드 0 할당 데 이 터 를 알 수 있다.  350455289,스 레 드 1 할당 데이터  -1313940209,모듈 AB 에서 받 은 data  그러나 스 레 드 1 할당 결과 일 뿐 입 니 다.이것 은 온라인 스 레 드 0 할당 후 AB 작업 전에 스 레 드 1 은 data 의 값 을 수정 했다 는 것 을 의미 합 니 다.  -1313940209 입 니 다.
간단 한 수정 은 다음 과 같다.

  package threadLocal;

import java.util.Random;

/**
 *           
 * @author jingfn
 *
 */
public class ThreadScopeShareDate {
	private static int data ;
	public static void main(String[] args) {
		for(int i=0;i<2;i++)
		new Thread(new Runnable(){
			public  void run(){
				synchronized(ThreadScopeShareDate.class){
					data = new Random().nextInt();
					System.out.println(Thread.currentThread().getName()+"--put data "+data);
					new A().get();
					new B().get();
				}
			}
		}).start();
	}

	static class A{
		private void get(){
			System.out.println("A--get data from "+Thread.currentThread().getName()+" of "+data);
		}
	}
	static class B{
		private void get(){
			System.out.println("B--get data from "+Thread.currentThread().getName()+" of "+data);
		}
	}
}


결 과 는 다음 과 같다. 

Thread-0--put data -30716152
A--get data from Thread-0 of -30716152
B--get data from Thread-0 of -30716152
Thread-1--put data 913737008
A--get data from Thread-1 of 913737008
B--get data from Thread-1 of 913737008

현재 스 레 드 와 데 이 터 를 연결 하면 ThreadLocal 같은 종 류 를 이용 할 수 있 습 니 다.
ThreadLocal 은 하나의 Map 에 해당 합 니 다.key 는 현재 스 레 드 입 니 다.value 는 현재 스 레 드 에 대응 하 는 값 입 니 다.그러면 위의 코드 를 개조 하여 아래 의 코드 를 얻 을 수 있 습 니 다.

 package threadLocal;

import java.util.Random;

/**
 *           
 * @author jingfn
 *
 */
public class ThreadScopeShareDate {
	private static int data ;
	private static ThreadLocal<Integer> localdata = new ThreadLocal<Integer>();
	public static void main(String[] args) {
		for(int i=0;i<2;i++)
		new Thread(new Runnable(){
			public  void run(){
				synchronized(ThreadScopeShareDate.class){
					data = new Random().nextInt();
					localdata.set(data);
					System.out.println(Thread.currentThread().getName()+"--put data "+data);
					new A().get();
					new B().get();
				}
			}
		}).start();
	}

	static class A{
		private void get(){
			System.out.println("A--get data from "+Thread.currentThread().getName()+" of "+localdata.get());
		}
	}
	static class B{
		private void get(){
			System.out.println("B--get data from "+Thread.currentThread().getName()+" of "+localdata.get());
		}
	}
}





코드 가 실 행 된 후에 같은 효 과 를 얻 을 수 있 습 니 다.
        다음 질문 이 하나 더 있 습 니 다.  위 에서 논의 해 온 것 은 스 레 드 간 에 변 수 를 공유 하 는 것 입 니 다.그러면 여러 변수 라면 요?
        ThreadLocal 을 직접 하려 면 매번 하나의 변수 만 현재 스 레 드 와 연결 할 수 있 습 니 다.여러 변수 가 현재 스 레 드 와 연결 하려 면 여러 개의 ThreadLocal 대상 이 이렇게 하 는 것 은 분명 합 리 적 이지 않 습 니 다.그럼 어떻게 처리 할 까요?
        ThreadLocal 은 하나의 변수 와 만 연결 할 수 있 기 때문에 이 변 수 를 하나의 변수의 용기 로 설정 할 수 있 습 니 다.용기 에 여러 개의 변 수 를 존재 할 수 있 습 니 다.이것 은 현재 스 레 드 와 연결 해 야 하 는 변 수 를 하나의 실체 클래스 에 밀봉 하 는 것 입 니 다.

package threadLocal;

import java.util.Random;

/**
 *           
 * @author jingfn
 *
 */
public class ThreadScopeShareDateContainer {
	private static int data ;
	public static void main(String[] args) {
		for(int i=0;i<2;i++)
		new Thread(new Runnable(){
			public  void run(){
				synchronized(ThreadScopeShareDateContainer.class){
					data = new Random().nextInt();
					Container.getInstance().setData1(data);
					Container.getInstance().setData2(data);
					System.out.println(Thread.currentThread().getName()+"--put data "+data);
					new A().get();
					new B().get();
				}
			}
		}).start();
	}

	static class A{
		private void get(){
			System.out.println("A--get data from "+Thread.currentThread().getName()+" of "+Container.getInstance().getData1()+"--"+Container.getInstance().getData2());
		}
	}
	static class B{
		private void get(){
			System.out.println("B--get data from "+Thread.currentThread().getName()+" of "+Container.getInstance().getData1()+"--"+Container.getInstance().getData2());
		}
	}
}

 class Container{
	 private int data1,data2;
	 private static ThreadLocal<Container> local = new ThreadLocal<Container>();
	 public static Container getInstance(){
		 Container container = local.get();;
		 if(container == null){
			 container = new Container();
			 local.set(container);
		 }
		 return container;
	 }
	public int getData1() {
		return data1;
	}
	public void setData1(int data1) {
		this.data1 = data1;
	}
	public int getData2() {
		return data2;
	}
	public void setData2(int data2) {
		this.data2 = data2;
	}


 }



  ThreadLocal 은 동시 다발 프로그램의 해결 방안 이다.그 는 공간 을 이용 하여 시간 을 바 꾸 는 것 이다.즉,모든 스 레 드 에 공간 을 분배 하여 다 중 스 레 드 를 실현 하 는 것 이다.ThreadLocal 은 자 물 쇠 를 전혀 사용 하지 않 기 때문에 그 는 데이터 공유 의 자물쇠 가 아니다.성능 상 ThreadLocal 은 절대적 인 우 위 를 가지 지 못 하지만 자 물 쇠 를 전혀 사용 하지 않 는 다 중 스 레 드 솔 루 션 으로서 높 은 병발 상황 에서 어느 정도 자물쇠 경쟁 을 줄 일 수 있다.

좋은 웹페이지 즐겨찾기