public class Printer {
public Printer() {
}
public synchronized void print1() {
for (int i = 0; i < 3; i++) {
System.out.print(i);
}
}
public synchronized void print2() {
for (int i = 3; i < 6; i++) {
System.out.print(i);
}
}
public static void main(String[] args) {
Printer printer = new Printer();
new Thread(() -> {
printer.print1();
}).start();
new Thread(() -> {
printer.print2();
}).start();
}
}
각 메서드에 개별적으로 synchronized
처리가 되어있다. 한 메서드가 독점적으로
락을 점유하므로 012345
혹은 345012
와 같이 순차적으로 실행된다.
public class Printer {
public Printer() {
}
public synchronized void print1() {
for (int i = 0; i < 3; i++) {
System.out.print(i);
}
}
public void print2() {
for (int i = 3; i < 6; i++) {
System.out.print(i);
}
}
public static void main(String[] args) {
Printer printer = new Printer();
new Thread(() -> {
printer.print1();
}).start();
new Thread(() -> {
printer.print2();
}).start();
}
}
print1
메서드에는 synchronized
처리가 되어있지만 print2
에는
동기화 처리가 되어있지 않다. 따라서 print1
의 실행중 print2
의 개입이
가능하므로 340125, 012345, 345012, 304152
와 같은 실행 형태가 가능하다.
public class Printer {
public Printer() {
}
public void print1() {
synchronized (this) {
for (int i = 0; i < 3; i++)
System.out.print(i);
}
}
public synchronized void print2() {
for (int i = 3; i < 6; i++)
System.out.print(i);
}
public static void main(String[] args) {
Printer printer = new Printer();
new Thread(() -> {
printer.print1();
}).start();
new Thread(() -> {
printer.print2();
}).start();
}
}
print1
에서는 synchronized(this)
를 통해 인스턴스에 대한 락을 점유하고
있다. 따라서, print1->print2
혹은 print2->print1
의 실행 순서가 가능하여
012345, 345012
와 같은 형태가 도출된다.
public class Printer {
public Printer() {
}
public void print1() {
synchronized (obj1) {
for (int i = 0; i < 3; i++)
System.out.print(i);
}
}
public synchronized void print2() {
for (int i = 3; i < 6; i++)
System.out.print(i);
}
private final Object obj1 = new Object();
public static void main(String[] args) {
Printer printer = new Printer();
new Thread(() -> {
printer.print1();
}).start();
new Thread(() -> {
printer.print2();
}).start();
}
}
print1
에서는 실행되는 메서드들과 상관 없는 obj1
에 락을 걸고 있다.
따라서 print1
과 print2
과 뒤섞여 실행되는 형태가 도출된다.
340125, 012345, 345012, 304152
public class Printer {
public Printer() {
}
public synchronized static void print1() {
for (int i = 0; i < 3; i++)
System.out.print(i);
}
public synchronized void print2() {
for (int i = 3; i < 6; i++)
System.out.print(i);
}
public static void main(String[] args) {
Printer printer = new Printer();
new Thread(() -> {
Printer.print1();
}).start();
new Thread(() -> {
printer.print2();
}).start();
}
}
print1
은 static
메서드이고 synchronized
로 락이 클래스 단위에 걸리게
된다. 따라서 print1
과 print2
의 실행이 뒤섞여 나타날 수 있다.
public class Printer {
public Printer() {
}
public static void print1() {
synchronized (Printer.class) {
for (int i = 0; i < 3; i++) {
System.out.print(i);
}
}
}
public synchronized static void print2() {
for (int i =3; i < 6; i++) {
System.out.print(i);
}
}
public static void main(String[] args) {
new Thread(() -> {
Printer.print1();
}).start();
new Thread(() -> {
Printer.print2();
}).start();
}
}
print1
은 클래스에 락을 걸고 있고, print2
는 static
메서드이며
synchronized
처리시 역시 클래스 단위로 락을 걸게 된다. 따라서 순차적인
실행 형태인 012345
혹은 345012
가 가능하다.