Java에서 변수를 동기화하거나 잠그는 방법은 무엇입니까?
이 작고 간단한 샘플을 사용하겠습니다.
class Sample {
private String msg = null;
public void newmsg(String x){
msg = x;
}
public String getmsg(){
String temp = msg;
msg = null;
return temp;
}
}
newmsg()
내가 액세스 할 수없는 다른 스레드 에서 함수 를 호출했다고 가정 해 보겠습니다 .
synchonize 메서드를 사용하여 문자열 msg
이 한 번에 하나의 함수에서만 사용 되도록 보장하고 싶습니다 . 즉, 함수는와 newmsg()
동시에 실행할 수 없습니다 getmsg()
.
매우 쉽습니다.
class Sample {
private String message = null;
private final Object lock = new Object();
public void newMessage(String x) {
synchronized (lock) {
message = x;
}
}
public String getMessage() {
synchronized (lock) {
String temp = message;
message = null;
return temp;
}
}
}
나는 것을 참고 하지 않았다 중 자신이 동기화 방법을 만들거나 동기화 this
. 의도적으로 잠금을 노출 하지 않는 한, 코드 만 액세스 할 수있는 객체에 대해서만 잠금을 획득하는 것이 좋습니다 . 다른 어떤 것도 코드와 다른 순서로 잠금을 획득하지 않을 것이라는 확신을 훨씬 쉽게 만들어줍니다.
이 기능의 경우 잠금을 전혀 사용하지 않는 것이 좋습니다. AtomicReference를 사용해보십시오.
public class Sample {
private final AtomicReference<String> msg = new AtomicReference<String>();
public void setMsg(String x) {
msg.set(x);
}
public String getMsg() {
return msg.getAndSet(null);
}
}
잠금이 필요하지 않으며 코드는 더 간단합니다. 어쨌든 그것은 당신이 원하는 것을 수행하는 표준 구조를 사용합니다.
Java 1.5부터는 항상 java.util.concurrent 패키지를 고려하는 것이 좋습니다. 그들은 현재 자바의 최첨단 잠금 메커니즘입니다. 동기화 메커니즘은 java.util.concurrent 클래스보다 더 무겁습니다.
예제는 다음과 같습니다.
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Sample {
private final Lock lock = new ReentrantLock();
private String message = null;
public void newmsg(String msg) {
lock.lock();
try {
message = msg;
} finally {
lock.unlock();
}
}
public String getmsg() {
lock.lock();
try {
String temp = message;
message = null;
return temp;
} finally {
lock.unlock();
}
}
}
이 간단한 예제 에서는 두 메서드 시그니처 synchronized
뒤에 수정 자로 넣을 수 있습니다 public
.
더 복잡한 시나리오에는 다른 것들이 필요합니다.
synchronized
키워드를 사용하십시오 .
class sample {
private String msg=null;
public synchronized void newmsg(String x){
msg=x;
}
public synchronized string getmsg(){
String temp=msg;
msg=null;
return msg;
}
}
synchronized
메서드에 키워드를 사용 하려면 스레드가의 인스턴스에 대한 잠금을 획득해야합니다 sample
. 따라서 한 스레드가에있는 newmsg()
경우 다른 스레드는 sample
을 호출하려고하더라도 의 인스턴스에 대한 잠금을 얻을 수 없습니다 getmsg()
.
On the other hand, using synchronized
methods can become a bottleneck if your methods perform long-running operations - all threads, even if they want to invoke other methods in that object that could be interleaved, will still have to wait.
IMO, in your simple example, it's ok to use synchronized methods since you actually have two methods that should not be interleaved. However, under different circumstances, it might make more sense to have a lock object to synchronize on, as shown in Joh Skeet's answer.
If on another occasion you're synchronising a Collection rather than a String, perhaps you're be iterating over the collection and are worried about it mutating, Java 5 offers:
참고URL : https://stackoverflow.com/questions/5861894/how-to-synchronize-or-lock-upon-variables-in-java
'programing tip' 카테고리의 다른 글
누구나 간단한 Java 웹 앱 프레임 워크를 추천 할 수 있습니까? (0) | 2020.11.16 |
---|---|
PHPExcel 첫 번째 행을 굵게 만들기 (0) | 2020.11.16 |
Django Admin에서 삭제 링크를 비활성화하는 방법 (0) | 2020.11.16 |
LINQ to SQL 트랜잭션을 만드는 방법은 무엇입니까? (0) | 2020.11.15 |
Linux 커널 : 시스템 호출 후킹 예제 (0) | 2020.11.15 |