여러 스레드가 동일한 리소스를 공유(액세스)할 수 있습니다.
예를 들어 동일한 개체, 동일한 변수, 동일한 파일에 액세스합니다.
여러 스레드가 동일한 리소스에 액세스하면 데이터 혼란이 발생하기 쉽습니다. 스레드 안전 문제라고 불리는 데이터 보안 문제
어떤 상황에서 스레드 안전 문제가 발생합니까?
여러 스레드가 동일한 리소스를 공유합니다
그리고 적어도 하나의 스레드가 쓰기 작업을 수행합니다
입금 쓰레드와 출금 쓰레드가 각각 2개가 있습니다
1000-1------»999입금 출금 쓰레드 1 잔액 쓰레드 2
1000 «----1000------» 1000
1000 "----1000------" 1000
1000+1000--- - -》2000
티켓 판매
스레드 1 투표 수 스레드 2
999 «------1000 -1
정확함 : end 최종 잔액은 999가 아닌 998이어야 합니다티켓 구매 문제 오류(스레드 동기화되지 않음) 예:public class love implements Runnable{ private int piao=3000;//有3000张票 public boolean sale() {//ture代表还有票;false代表没有票了 if(piao<1) return false; piao--;//卖1张票 //细化piao--; //寄存器=piao; //寄存器=寄存器-1; //piao=寄存器; String sk =Thread.currentThread().getName();//获取当前线程(买票窗口)的名字 System.out.println(sk+"卖了1张票,还剩下"+piao+"张"); return piao>1; } public void run() { while(sale());//循环执行;直至卖完票返回false } } public class Main { public static void main(String[] a) { love tjlove =new love(); for(int i=1;i<=4;i++) {//循环4次;产生4个线程(窗口)卖票 Thread tj = new Thread(tjlove()); tj.setName(""+i); tj.start(); } } }부분 출력 결과:
스레드 안전 문제
분석 문제
클래스 1 변수 값의 스레드 A와 B는 +1 연산에 대해 17입니다
최종 결과는 2 18Solution잠금:
이렇게 하면 하나의 스레드만 동시에 액세스할 수 있으므로 안전이 보장됩니다. 이전 오류는 이러한 스레드가 함께 액세스했기 때문이었습니다.
스레드 동기화에는 Java의 두 가지 방법이 있습니다:
1. 동기화 문
public class love implements Runnable{ private int piao=3000;//本人cpu单核性能过强,数据量大些才能看到是4个线程在卖票 public boolean sale() { synchronized(this) {//1个线程获取这个对象的锁,并加锁; synchronized作用于整个语句 //this指向当前对象 //不能用new Object();这样会产生新的对象,产生新的锁 //把this换成"123",效果基本一样;因为其存在常量值里,每次访问的对象一样 if(piao<1) return false; piao--; String sk =Thread.currentThread().getName(); System.out.println(sk+"卖了1张票,还剩下"+piao+"张"); return piao>0; } } public void run() { while(sale()); } }부분 출력 결과:
동기화(obj)의 원리
1. 각 개체에는 이와 관련된 고유 잠금(intrinsic lock) 또는 모니터 잠금(monitor lock)이 있습니다.
3. 하나의 스레드가 내부 잠금을 보유하고 있는 한 다른 스레드는 더 이상 동시에 이 잠금을 획득할 수 없습니다
✓ 이 잠금을 획득하려고 하면 BLOCKED 상태가 됩니다
4. 여러 스레드가 동일한 동기화(obj) 문에 액세스하는 경우obj는 동기화를 달성하기 위해 동일한 개체여야 합니다동기화 방법public class love implements Runnable{ private int piao=3000; public synchronized boolean sale() { //synchronized作用于整个方法 if(piao<1) return false; piao--; String sk =Thread.currentThread().getName(); System.out.println(sk+"卖了1张票,还剩下"+piao+"张"); return piao>0; } public void run() { while(sale()); } }동기화할 수 없습니다. 생성자를 수정하세요 동기화 메서드의 본질 인스턴스 메서드: 동기화(this) 정적 메서드: 동기화(클래스 객체) 동기화 문은 동기 메서드보다 유연합니다. 동기화 문은 필요한 사항을 정확하게 제어할 수 있습니다. 추가 코드 범위를 잠그고 BLOCKED 상태의 스레드를 줄여 노동력을 최대한 활용하세요스레드 동기화 기술을 사용한 후스레드 안전성 문제는 해결되었으나 프로그램의 실행 효율성을 떨어뜨립니다 잠금으로 인해 사람들이 기다리게 됩니다. 스레드에는 추가 잠금 및 잠금 해제 작업이 있습니다따라서 정말 필요할 때만 스레드 동기화 기술을 사용하세요
위 내용은 Java 스레드 안전성 및 동기화 예시 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!