synchronized

yshjft·2023년 1월 9일
0

Java, OOP

목록 보기
24/27

synchronized 메서드

동일한 인스턴스

public class Main {
    public static void main(String[] args) throws InterruptedException{
        sameInstance();
    }

    private static void sameInstance() {
        A a = new A();
        Thread thread1 = new Thread(() -> {
            a.run("thread1");
        });
        Thread thread2 = new Thread(() -> {
            a.run("thread2");
        });

        thread1.start();
        thread2.start();
    }
}

public class A {
    public synchronized void run(String name) {
        System.out.println(name+" lock");
        try {
            Thread.sleep(1000);
        }catch(InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+" unlock");
    }

    public void print(String name) {
        System.out.println(name+" hello");
    }
}
  • 동기화 적용(thread1 → thread2)

서로 다른 인스턴스

public class Main {
    public static void main(String[] args) throws InterruptedException{
        differentInstance();
    }

    private static void differentInstance() {
        A a1 = new A();
        A a2 = new A();
        Thread thread1 = new Thread(() -> {
            a1.run("thread1");
        });

        Thread thread2 = new Thread(() -> {
            a2.run("thread2");
        });

        thread1.start();
        thread2.start();
    }
}
  • 동기화 안됨
  • 서로 다른 인스턴스는 lock을 공유하지 않는다.

동일 인스턴스 & synchronized 메서드 & non-synchronized 메서드

public class Main {
	public static void main(String[] args) throws InterruptedException{
        printWithOutSynchronized();
    }

    private static void printWithOutSynchronized() throws InterruptedException {
        A a = new A();
        Thread thread1 = new Thread(() -> {
            a.run("thread1");
        });
        Thread thread2 = new Thread(() -> {
            a.print("thread2");
        });

        thread1.start();
        Thread.sleep(500);
        thread2.start();
    }
}
  • 동기화 안됨
  • synchronized는 인스턴스 접근 자체에 락을 거는 것은 아니다.

동일 인스턴스 & synchronized 메서드

public class B {
    public synchronized void print(String name) {
        System.out.println(name+" hello");
    }
    
    public synchronized void run(String name) {
        System.out.println(name+" lock");
        try {
            Thread.sleep(1000);
        }catch(InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+" unlock");
    }
}

public class Main {
    public static void main(String[] args) throws InterruptedException{
        printWithSynchronized();
    }
    
    private static void printWithSynchronized() throws InterruptedException {
        B b = new B();
        Thread thread1 = new Thread(() -> {
            b.run("thread1");
        });
        Thread thread2 = new Thread(() -> {
            b.print("thread2");
        });

        thread1.start();
        Thread.sleep(500);
        thread2.start();
    }
}
  • 동기화
  • 인스턴스에 lock을 거는 synchronized 키워드는 synchronized가 적용된 메서드끼리 일괄적으로 lock을 공유한다.

서로 다른 인스턴스 & static synchronized 메서드

public class C {
    public static synchronized void run(String name) {
        System.out.println(name+" lock");
        try {
            Thread.sleep(1000);
        }catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+" unlock");
    }

    public synchronized void print(String name) {
        System.out.println(name+ " hello");
    }
}

public class Main {
    public static void main(String[] args) throws InterruptedException{
    	synchronizedWithStaticMethod();
    }
   
   	 private static void synchronizedWithStaticMethod() {
        C c1 = new C();
        C c2 = new C();
        Thread thread1 = new Thread(() -> {
            c1.run("thread1");
        });

        Thread thread2 = new Thread(() -> {
            c2.run("thread2");
        });

        thread1.start();
        thread2.start();
    }
}
  • 동기화 적용
  • static이 붙은 synchronized는 클래스 단위로 lock을 건다.(다른 인스턴스라도 lock을 공유한다.)

서로 다른 인스턴스 & static synchronized 메서드 & non-static synchronized 메서드

public class Main {
    public static void main(String[] args) throws InterruptedException{
    	 synchronizedWithStaticAndNonStatic();
    }
    
    private static void synchronizedWithStaticAndNonStatic() {
        C c1 = new C();
        C c2 = new C();
        Thread thread1 = new Thread(() -> {
            c1.run("thread1");
        });

        Thread thread2 = new Thread(() -> {
            c2.print("thread2");
        });

        thread1.start();
        thread2.start();
    }
}
  • 동기화 적용 안됨
  • static synchronized method와 synchronized method의 lock은 공유되지 않는다.

참고

Java - synchronized 동기화

profile
꾸준히 나아가자 🐢

0개의 댓글