여러 스레드가 동일한 리소스를 공유(액세스)할 수 있습니다.
예를 들어 동일한 개체, 동일한 변수, 동일한 파일에 액세스합니다.
여러 스레드가 동일한 리소스에 액세스하면 데이터 혼란이 발생하기 쉽습니다. 스레드 안전 문제라고 불리는 데이터 보안 문제
어떤 상황에서 스레드 안전 문제가 발생합니까?
여러 스레드가 동일한 리소스를 공유합니다
그리고 적어도 하나의 스레드가 쓰기 작업을 수행합니다
입금 쓰레드와 출금 쓰레드가 각각 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()); } }
위 내용은 Java 스레드 안전성 및 동기화 예시 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!