변수 와 스 레 드 보안
20389 단어 스 레 드 보안
이 를 통 해 변수 유형 과 스 레 드 안전 에 대한 사 고 를 했 고 인터넷 에 있 는 자 료 를 참고 하여 테스트 를 한 결과 ThreadLocal 과 국부 변수 안전 을 제외 하고 정적 과 인 스 턴 스 변 수 는 모두 안전 하지 않다 는 것 을 발견 했다.이제 하나씩 말 해 봐.
우선 정적 변수 (클래스 변수) 를 봅 니 다.
1 package org.thread;
2 /**
3 *
4 * @author winkey
5 *
6 */
7 public class StaticVar {
8
9 public static void main(String[] args) {
10 Runnable accumelatora = new Accumulatort();
11 Thread threada = new Thread(accumelatora, "ThreadA");
12 Thread threadb = new Thread(accumelatora, "ThreadB");
13 threada.start();
14 threadb.start();
15 }
16
17 }
18
19 class Accumulatort implements Runnable {
20 //
21 private static int local = 0;
22 @SuppressWarnings("unchecked")
23 public void run() {
24 //
25 for (int i = 0; i <= 10; i++) {
26 local += 1;
27 try {
28 Thread.sleep(500);
29 } catch (Exception e) {
30 }
31 System.out.println(Thread.currentThread().getName() + "-->"
32 + local);
33 }
34 }
35 }
실행 후 콘 솔 출력 을 보면 특정한 스 레 드 가 변 수 를 사용 할 때 다른 스 레 드 에 의 해 수정 되 었 음 을 알 수 있 습 니 다.
정적 변 수 는 정적 저장 방식 이기 때문에 정적 저장 방식 이란 프로그램 이 실행 되 는 동안 고정된 저장 공간 을 분배 하 는 방식 을 말한다.즉, 아무리 많은 스 레 드 가 있어 도 방문 은 하나의 변수 이 고 안전 문 제 는 분명 하 다.
다시 말 하면 인 스 턴 스 변수:
1 package org.thread;
2 /**
3 * scope=singleton ,
4 * @author winkey
5 *
6 */
7 public class InstanceVar {
8
9 public static void main(String[] args) {
10 Runnable accumelatora = new Accumulatort2();
11 Thread threada = new Thread(accumelatora, "ThreadA");
12 Thread threadb = new Thread(accumelatora, "ThreadB");
13 threada.start();
14 threadb.start();
15 }
16
17 }
18
19 class Accumulatort2 implements Runnable {
20 //
21 int locals = 0;
22 @SuppressWarnings("unchecked")
23 public void run() {
24 for (int i = 0; i <= 10; i++) {
25 locals += 1;
26 try {
27 Thread.sleep(1000);
28 } catch (Exception e) {
29 }
30 System.out.println(Thread.currentThread().getName() + "-->"
31 + locals);
32 }
33 }
34 }
안전 할 것 이 라 고 생각 할 지 모 르 지만, 운행 후 안전 문 제 는 곧 발견 할 것 이다.결 과 는 static 와 같 습 니 다.
인 스 턴 스 변 수 는 대상 인 스 턴 스 의 개인 적 인 것 입 니 다. 자바 가상 컴퓨터 의 더미 에서 분 배 됩 니 다. 시스템 에 이 대상 의 인 스 턴 스 만 존재 한다 면 다 중 스 레 드 환경 에서 정적 변수 처럼 특정한 스 레 드 에 의 해 수 정 된 후에 다른 스 레 드 는 수정 을 모두 볼 수 있 기 때문에 스 레 드 가 안전 하지 않 습 니 다.모든 스 레 드 가 서로 다른 대상 에서 실 행 될 경우 대상 과 대상 간 의 인 스 턴 스 변수의 수정 은 서로 영향 을 주지 않 기 때문에 스 레 드 가 안전 합 니 다. 위 에서 우 리 는 두 개의 라인 이지 만 대상 은 하나 이기 때문에 네가 생각 하 는 안전 이 아니다.
부분 변수:
1 package org.thread;
2 /**
3 *
4 * @author winkey
5 *
6 */
7 public class LocalVar {
8
9 public static void main(String[] args) {
10 Runnable accumelatora = new Accumulatort3();
11 Thread threada = new Thread(accumelatora, "ThreadA");
12 Thread threadb = new Thread(accumelatora, "ThreadB");
13 threada.start();
14 threadb.start();
15 }
16
17 }
18
19 class Accumulatort3 implements Runnable {
20 @SuppressWarnings("unchecked")
21 public void run() {
22 //
23 int locals = 0;
24 for (int i = 0; i <= 10; i++) {
25 locals += 1;
26 try {
27 Thread.sleep(1000);
28 } catch (Exception e) {
29 }
30 System.out.println(Thread.currentThread().getName() + "-->"
31 + locals);
32 }
33 }
34 }
안 되면 몇 번 더 운행 해. 괜찮아, 스 레 드 안전 해.
모든 스 레 드 가 실 행 될 때 부분 변 수 를 각 스 택 프레임 의 작업 메모리 에 두 고 스 레 드 간 에 공유 되 지 않 기 때문에 안전 문제 가 없습니다.
일반적으로 다 중 스 레 드 프로 그래 밍 을 할 때 가장 생각 나 는 것 은 ThreadLocal 입 니 다.
ThreadLocal 사용 장 소 는 주로 다 중 스 레 드 에서 데이터 데이터 데이터 가 병발 로 인해 일치 하지 않 는 문 제 를 해결 합 니 다.ThreadLocal 은 모든 스 레 드 의 동시 방문 데이터 에 복사 본 을 제공 하고 복사 본 을 방문 하여 업 무 를 수행 합 니 다. 이러한 결 과 는 메모리 가 소모 되 었 고 스 레 드 동기 화가 가 져 온 성능 소 모 를 크게 줄 였 으 며 스 레 드 병행 제어 의 복잡 도 를 줄 였 습 니 다.
이 클래스 는 스 레 드 부분 (thread - local) 변 수 를 제공 합 니 다.이 변 수 는 일반적인 대응 물 과 다 릅 니 다. 변 수 를 방문 하기 때 문 입 니 다. get 혹시 set 방법) 모든 스 레 드 는 변수의 초기 화 복사 본 에 독립 된 부분 변 수 를 가지 고 있 습 니 다.ThreadLocal 인 스 턴 스 는 보통 클래스 의 private static 필드 입 니 다. 상 태 를 특정한 스 레 드 (예 를 들 어 사용자 ID 나 트 랜 잭 션 ID) 와 연결 하 기 를 원 합 니 다.
1 package org.thread;
2
3 public class ThreadLocalVar {
4 //
5 @SuppressWarnings("unchecked")
6 public static ThreadLocal threadLocal = new ThreadLocal();
7
8 public static void main(String[] args) {
9 Runnable accumelatora = new Accumulatort4();
10 Thread threada = new Thread(accumelatora, "ThreadA");
11 Thread threadb = new Thread(accumelatora, "ThreadB");
12 threada.start();
13 threadb.start();
14 }
15
16 }
17
18 class Accumulatort4 implements Runnable {
19 @SuppressWarnings("unchecked")
20 public void run() {
21 //
22 ThreadLocal threadLocal = ThreadLocalVar.threadLocal;
23 for (int i = 1; i <= 10; i++) {
24 if (threadLocal.get() == null)
25 threadLocal.set(new Integer(0));
26 int x = ((Integer) threadLocal.get()).intValue();
27 x += 1;
28 threadLocal.set(new Integer(x));
29 try {
30 Thread.sleep(1000);
31 } catch (InterruptedException e) {
32 }
33 System.out.println(Thread.currentThread().getName() + "-->"
34 + ((Integer) threadLocal.get()).intValue());
35 }
36 }
37 }
위의 코드 는 사실 모든 라인 에 자신의 변수 복사 본 이 있 기 때문에 안전 에 문제 가 없 을 것 이다.
그것 과 synchronized 의 차 이 는 모두 스 레 드 안전 을 위 한 것 이지 만 본질 적 인 차이 이다.
synchronized 는 잠 금 체 제 를 이용 하여 변수 나 코드 블록 을 한 스 레 드 에 만 접근 할 수 있 도록 합 니 다.한편, ThreadLocal 은 모든 스 레 드 에 변수의 복사 본 을 제공 하여 모든 스 레 드 가 특정한 시간 에 같은 대상 이 아니 라 여러 스 레 드 가 데이터 에 대한 데이터 공 유 를 격 리 시 켰 다.반면 Synchronized 는 반대로 여러 스 레 드 간 통신 시 데이터 공 유 를 얻 을 수 있 습 니 다.Synchronized 는 스 레 드 간 데이터 공유 에 사용 되 고 ThreadLocal 은 스 레 드 간 데이터 격 리 에 사 용 됩 니 다.물론 ThreadLocal 은 synchronized 를 대체 할 수 없습니다. 서로 다른 문제 영역 을 처리 합 니 다.synchronized 는 다 중 스 레 드 환경 에서 의 데이터 동기 화 를 처리 하 는 데 사용 되 며, ThreadLocal 은 현재 스 레 드 의 개인 적 인 상 태 를 저장 하기 위 한 것 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
스 레 드 보안 과 자원 공유 (Thread Safety and Shared Resources)위의 예 에서 부분 대상 의 인 스 턴 스 는 방법 method 2 에 의 해 되 돌아 오지 않 았 고 someMethod () 방법 외 에 이 부분 대상 을 방문 할 수 있 는 다른 대상 에 게 전달 되 지 않 았...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.