사용자마다 독립된 라인 동기화
6528 단어 사용자마다 독립된 라인 동기화
더 많은 움직임에 표시되지 않습니다. 그러면 사용자가 20초 안에 여러 번 공유하면 한 번의 움직임만 표시됩니다.
이때 모든 사용자의 공유 조작을 독립적으로 동기화해야 한다. 여러 개의 공유 조작이 있어도 동기화하고 20초 간격으로 실행해야 한다.
사용자마다 다른 맵 대상을 만들고 이 대상을 자물쇠로 사용합니다
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
public class UserThread {
public static Map<String, Object> map = new HashMap<String, Object>();//
// map
static{
long perHour = 1000*60*60;
Timer perHourTimer = new Timer();
perHourTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
map.clear();
}
}, perHour, perHour);
}
public static void syn(int userId){
String key = userId+"";
Object obj = map.get(key);
if(obj == null){
obj = new String(key);
map.put(key, obj);
}
synchronized (obj) {
try {
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName());
} catch (Exception e) {
}
}
}
/**
* :
* (1) 、 、 3 , ,6
* (2) ,3 , 6
*/
public static void main(String[] args) {
Thread t1 = new Thread(){
public void run() {
UserThread.syn(1);
};
};
t1.setName(" ");
t1.start();
Thread t2 = new Thread(){
public void run() {
UserThread.syn(1);
};
};
t2.setName(" ");
t2.start();
Thread t3 = new Thread(){
public void run() {
UserThread.syn(2);
};
};
t3.setName(" ");
t3.start();
Thread t4 = new Thread(){
public void run() {
UserThread.syn(3);
};
};
t4.setName(" ");
t4.start();
}
}
왜 맵으로 자물쇠를 저장해야 하는지,userId+를 자물쇠 대상으로 직접 사용하면 이런 효과를 얻지 못할까,
왜 이렇게 귀찮게 굴어?그럼 이제 우리 이렇게 한번 해보자.
public class UserThread {
public static void syn(int userId){
Object obj = userId+"";
synchronized (obj) {
try {
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName());
} catch (Exception e) {
}
}
}
/**
*
*/
public static void main(String[] args) {
Thread t1 = new Thread(){
public void run() {
UserThread.syn(1);
};
};
t1.setName(" ");
t1.start();
Thread t2 = new Thread(){
public void run() {
UserThread.syn(1);
};
};
t2.setName(" ");
t2.start();
Thread t3 = new Thread(){
public void run() {
UserThread.syn(2);
};
};
t3.setName(" ");
t3.start();
Thread t4 = new Thread(){
public void run() {
UserThread.syn(3);
};
};
t4.setName(" ");
t4.start();
}
}
, 。 Object
obj = userId+
""
; , main
public static void main(String[] args) {
String str1 = "";
String str2 = "";
System.out.println(str1 == str2);// true, , ,
String str3 = str1+str2;
System.out.println(str1 == str3);// false,str3 ,
// str3 ,
}
, , 。
한 마디로 하면 라인의 동기화는 자물쇠 대상을 바탕으로 이루어진 것이다. 이 대상을 뺏는 사람이 집행할 권한이 있다.
실행이 끝난 후 자물쇠를 풀고 뒤의 라인에서 계속 쟁탈합니다.
이상은 모두 같은 동기화가 필요한 코드 블록에 대한 토론이다. 그러면 서로 다른 코드 블록은 같은 대상을 자물쇠로 삼으면 어떤 결과가 나올까.
public class UserThread {
public static void syn(){
Object obj = "";
synchronized (obj) {
try {
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName());
} catch (Exception e) {
}
}
}
public static void syn2(){
Object obj = "";
synchronized (obj) {
try {
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName());
} catch (Exception e) {
}
}
}
/**
*
*/
public static void main(String[] args) {
Thread t1 = new Thread(){
public void run() {
UserThread.syn();
};
};
t1.setName(" ");
t1.start();
Thread t2 = new Thread(){
public void run() {
UserThread.syn2();
};
};
t2.setName(" ");
t2.start();
}
}
따라서 어떤 동기화 조작을 하든지 자물쇠 대상은 한 라인에만 뺏길 수 있고 서로 다른 코드 블록은 특수한 수요가 아니라면
절대 같은 대상을 자물쇠로 사용하지 마라. 그렇지 않으면 프로그램 성능을 크게 떨어뜨릴 수 있다