자바 의 동기 화 잠 금 확인
11170 단어 자바 언어
잠 금 역할:다 중 스 레 드 가 같은 데 이 터 를 방문 할 때 데이터 에 대한 보 호 를 제공 하여 데이터 가 파괴 되 거나 일치 하지 않 는 것 을 방지 합 니 다.
본 고의 목적:독자 가 자바 의 동기 자물쇠 에 관 한 지식 을 명확 하 게 인식 하고 프로그램 에서 합 리 적 으로 사용 할 수 있 도록 돕는다
동기 자물쇠 로 생산자 소비자 모델 을 실현 하고 계속 내 려 다 볼 것 을 강력 히 건의 하 다.
생산자 소비자 단순 모델 코드 참조:
public class Main{
List list = new ArrayList();
public static void main(String[] args) throws Exception {
Main t = new Main();
Consumer consumer = t.new Consumer();
Producer producer = t.new Producer();
consumer.start();
producer.start();
}
class Consumer extends Thread{
@Override
public void run() {
while (true) {
synchronized (list) {
if (list.size() > 0) {
// list
for(int i = 0 ;i < list.size();i++) {
list.remove(i);
System.out.println(" 1 ");
}
}else{
// list ,
list.notifyAll();
list.wait();
}
}
}
}
}
class Producer extends Thread{
@Override
public void run() {
while (true) {
synchronized (list) {
if (list.size() == 0) {
// list
list.add(1);
System.out.println(" 1 ");
}else{
// ,
list.notifyAll();
list.wait();
}
}
}
}
}
이상 은 생산자 와 소비자 의 간단 한 모델 예시 이다.
전체 프로그램의 사고방식 은 두 개의 라인 을 시작 하 는 것 이다.하 나 는 자원 의 생산자 Producer 이 고,하 나 는 자원 의 소비자 Consumer 이 며,자원 의 용 기 는 list 이다.코드 논 리 는 생산자 가 list 에 자원 이 없다 는 것 을 발견 하면 하 나 를 추가 하고,있 으 면 라인 은 대기 상태 에 들 어가 고,소비 자 는 반대로 있 으 면 소비 하고 없 으 면 기다린다.
위의 절 차 는 우리 가 생각 하 는 방향 에 따라 진행 할 수 있 습 니 다.콘 솔 은 끊임없이 인쇄 하여 1 개,소비 1 개,생산 1 개,소비 1 개 를 생산 합 니 다.
만약 에 위의 모든 줄 코드 의 역할 을 뚜렷하게 이해 할 수 있다 면 동기 자물쇠 의 용법 과 기본 을 파악 할 수 있다 는 것 을 설명 한다.만약 에 아직 잘 모 르 면 위의 코드 와 관련 된 지식 점 을 상세 하 게 분석 하 겠 다.
첫 번 째:하나의 스 레 드 가 list 를 조작 할 때 다른 스 레 드 가 조작 할 수 없 도록 해 야 합 니 다.그렇지 않 으 면 데이터 가 일치 하지 않 는 상황 이 발생 할 수 있 으 므 로 list 에 잠 금 처 리 를 하여 다른 스 레 드 의 변경 을 방지 해 야 합 니 다.
두 번 째:wait(),notify(),notify All()방법 에 대해 간단하게 말 하면 이 몇 가지 방법 은 현재 스 레 드 를 기다 리 고 깨 우 는 방법 입 니 다.Object 류 의 방법 입 니 다.Object 는 모든 종류의 부모 클래스 이기 때문에 모든 대상 에 게 이 방법 이 있 습 니 다.
wait():현재 스 레 드 로 하여 금 이 대상 의 자 물 쇠 를 기다 리 게 합 니 다.그것 은 도대체 누구의 자물쇠 입 니까?호출 된 사람 은 누구의 자 물 쇠 를 가 져 옵 니 다.예 를 들 어 위 에서 list.wait()를 호출 했 습 니 다.이것 은 현재 스 레 드 를 기다 리 게 하 는 것 을 의미 합 니 다.wait()방법 을 호출 하 는 것 은 요구 가 있 습 니 다.현재 스 레 드 는 대상 의 자 물 쇠 를 가 져 야 wait()방법 을 호출 할 수 있 습 니 다.여기 있 는 독자 들 은 약간 어 지 러 울 수 있 습 니 다.자 물 쇠 를 가 져 야 wait()를 호출 할 수 있 습그럼 wait 호출 은 뭘 기다 리 는 거 예요?이것 은 다음 방법 과 관련 이 있 습 니 다.wait()를 호출 하 는 것 은 다른 스 레 드 가 notify()를 호출 하 는 방법 을 기다 리 는 것 입 니 다.
notify():이 방법 은 위의 wait 와 대응 하 는 것 입 니 다.이 자원 을 기다 리 는 스 레 드 를 깨 우 는 것 입 니 다.'아,형제 여,자 물 쇠 를 풀 겠 습 니 다.가 져 가서 사용 하 세 요!'그 다음 에 다른 특정한 스 레 드 는 자 물 쇠 를 가 져 와 서 계속 일 을 하 게 되 었 습 니 다.그리고 notify All 이라는 방법 도 있 습 니 다.역할 은 notify 와 같 습 니 다.jdk 의 설명 문서 에서 뚜렷 한 차이 가 없고 사용 효과 가 똑 같은 것 같 습 니 다.
대상 잠 금,클래스 잠 금,synchronized 동기 화 방법,그리고 synchronized 동기 화 코드 블록 은 도대체 무엇 입 니까?그들 사 이 는 또 어떤 관계 입 니까?
대상 잠 금 및 synchronzied 방법 은 다음 코드 를 보십시오.
// java ,obj1 obj2
Object obj1 = new Object();
Object obj2 = new Object();
synchronized 는 대상 의 동기 화 자 물 쇠 를 가 져 오 는 뜻 입 니 다.다음 코드 를 보십시오.
public void test1(){
synchronized(obj1){
System.out.println(" ....");
}
}
위의 코드 는 obj 1 대상 의 자 물 쇠 를 가 져 오 는 것 입 니 다.만약 에 obj 1 대상 의 자물쇠 가 다른 스 레 드 에 의 해 가지 고 있다 면 프로그램 은 synchronzied 에 멈 춰 서 obj 1 의 자 물 쇠 를 가 져 올 때 까지 계속 실 행 됩 니 다.
저희 가 자주 보 는 동기 코드 는 이 렇 습 니 다.
public class Main{
public synchronized void doInSyn(){
System.out.println(" .......");
}
}
스 레 드 는 doInSyn()방법 을 실행 할 때 먼저 현재 대상 의 자 물 쇠 를 가 져 와 야 실행 할 수 있 습 니 다.사실은 아래 와 같은 쓰기 효 과 를 가 집 니 다.
public class Main{
public void doInSyn(){
// this
synchronized(this){
System.out.println(" .......");
}
}
}
여기까지 대상 의 자 물 쇠 를 이 해 했 을 거 라 고 믿 지만,때때로 우 리 는 다음 과 같은 문법 을 볼 수 있다
public static synchronized doInSync(){
}
여기 synchronzied 는 현재 대상 의 동기 화 자 물 쇠 를 가 져 와 서 실행 하 는 것 입 니까?물론 답 은 부정 적 이기 때문에 다음 에 우리 가 말 하고 자 하 는 것 은 유형의 자물쇠 이다.이름과 대상 의 자물쇠 가 다 르 지만 사실은 원 리 는 같다.
자바 에서 정적 방법 은 클래스 에 속 하기 때문에 정적 방법의 자물쇠 도 클래스 의 자물쇠 입 니 다.
자바 의 정적 방법 은 클래스 에 속 합 니 다.다음은 코드 를 통 해 설명 하 겠 습 니 다.
public class ClassLockTest extends Thread {
public static void main(String[] args) {
ClassLockTest t1 = new ClassLockTest();
t1.setName("T_One");
ClassLockTest t2 = new ClassLockTest();
t2.setName("T_Two");
t1.start();
t2.start();
}
@Override
public void run() {
try {
print(this.getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static synchronized void print(String threadName){
int count = 5;
while(count-- > 0){
Thread.sleep(100);
System.out.println(threadName + " "+count);
}
}
}
:
T_One 4
T_One 3
T_One 2
T_One 1
T_One 0
T_Two 4
T_Two 3
T_Two 2
T_Two 1
T_Two 0
두 개의 스 레 드 를 동시에 시작 하여 인쇄 하 는 것 을 볼 수 있 지만 순서 가 전혀 어 지 럽 지 않 습 니 다.정적 동기 화 방법(static synchronized 수식)은 대상 의 자 물 쇠 를 먼저 가 져 온 다음 에 실행 합 니 다.가 져 오지 않 으 면 다른 스 레 드 가 실 행 될 때 까지 기 다 립 니 다.
위의 방법 은 이런 표기 법 과 같다.
public static void print(String threadName) {
synchronized(ClassLockTest.class){
int count = 5;
while(count-- > 0){
Thread.sleep(100);
System.out.println(threadName + " "+count);
}
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정규 표현 식 과 이상 처리프로그램 이 실행 되 기 시 작 했 고 이상 이 발생 한 후에 우 리 는 이상 한 유형, 이상 이 발생 한 줄 번 호 를 주목 해 야 합 니 다.오 류 는 프로그램 이 실행 되 는 과정 에서 발생 하 는 일련의 이상...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.