Java 스레드 동기화 상세 정보
1. 코드 블록 동기화
예는 다음과 같습니다.
public class SyncBlock {
static class DataWrap {
int i;
}
static class SyncBlockThread extends Thread {
private DataWrap date;
public SyncBlockThread(DataWrap dataWrap) {
this.date = dataWrap;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (date) {
date.i++;
try {
sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + " " + date.i);
}
}
}
}
public static void main(String[] args) {
// i
DataWrap dataWrap = new DataWrap();
new SyncBlockThread(dataWrap).start();
new SyncBlockThread(dataWrap).start();
new SyncBlockThread(dataWrap).start();
}
}
예시에서 순서대로 정수를 출력하기를 희망합니다.일반적으로 동기화 코드 블록은 잠금이 필요한 대상입니다. 일반적으로 병렬 접근이 필요한 공유 자원입니다. 모든 라인은 지정한 자원을 수정하기 전에 먼저 이 자원을 잠그고 잠금 기간에 다른 라인은 이 자원을 수정할 수 없습니다.이로써 라인의 안전성을 확보하였다.또한 슬립이나 yield를 호출할 때 자원 자물쇠를 양보하지 않습니다.
2. 동기화 방법
public class SyncMethod {
static class DataWrap{
int i;
public synchronized void valueGrow(){
i++;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
static class SyncMethodThread extends Thread {
DataWrap dataWrap;
public SyncMethodThread(DataWrap dataWrap){
this.dataWrap = dataWrap;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
dataWrap.valueGrow();
}
}
}
public static void main(String[] args) {
// Datawrap i
DataWrap dataWrap = new DataWrap();
new SyncMethodThread(dataWrap).start();
new SyncMethodThread(dataWrap).start();
new SyncMethodThread(dataWrap).start();
}
}
동기화 방법은synchronized 키워드로 수식된 어떤 방법이다. 동기화 방법은 이 대상 자체를 잠그기 때문에 한 라인이 특정한 대상의 동기화 방법을 호출한 후에 다른 라인이 이 대상의 다른 동기화 방법을 호출할 경우에도 이 대상의 자물쇠가 잠겨 있기 때문에 방출되기를 기다려야 한다.3. 동기식 잠금
동기화 잠금 객체를 정의하여 동기화를 수행하는 경우 동기화 잠금은 Lock 객체로 충당됩니다.
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SyncLock {
static class DataWrap{
Lock lock = new ReentrantLock();
int i;
public void valueGrow(){
lock.lock();
try {
i++;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + i);
} finally {
lock.unlock();
}
}
}
static class SyncLockThread extends Thread {
DataWrap dataWrap;
public SyncLockThread(DataWrap dataWrap){
this.dataWrap = dataWrap;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
dataWrap.valueGrow();
}
}
}
public static void main(String[] args) {
// Datawrap i
DataWrap dataWrap = new DataWrap();
new SyncLockThread(dataWrap).start();
new SyncLockThread(dataWrap).start();
new SyncLockThread(dataWrap).start();
}
}
자물쇠 대상을 사용하여 스레드 동기화를 실현하면 더욱 유연할 수 있다. 일부 자물쇠는 특정한 기능을 가지고 있는데 그 중에서 비교적 자주 사용하는 ReadWriteLock 읽기와 쓰기 자물쇠, ReentrantLock은 자물쇠를 다시 넣을 수 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.