사용자마다 독립된 라인 동기화

이전에 정보를 공유하는 제3자 플랫폼을 개발했기 때문에 공유 시간은 간격이 있다. 예를 들어 20초 안에 한 번만 공유할 수 있다.
더 많은 움직임에 표시되지 않습니다. 그러면 사용자가 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();
         
    }
     
}

따라서 어떤 동기화 조작을 하든지 자물쇠 대상은 한 라인에만 뺏길 수 있고 서로 다른 코드 블록은 특수한 수요가 아니라면
절대 같은 대상을 자물쇠로 사용하지 마라. 그렇지 않으면 프로그램 성능을 크게 떨어뜨릴 수 있다

좋은 웹페이지 즐겨찾기