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 동기화