JDK 1.8
전체 코드
Thread는 2개로 이름은 A, B로 지정
A는 B보다 1초 늦게 시작하게 처리
각 메소드는 5초 대기한다.
간단히
synchronized는 static이나 공유하는 Class에서 대해서는 동시 접근이 되지 않는다. 해당 메소드가 아닌 class내의 모든 synchronized에 접근이 되지 않음
synchronized를 사용하지 않는 메소드는 접근이 가능하다.
class SyncClass{
public void basic(String name) {
System.out.println("basic: " + name);
}
private Object lockObject = new Object();
public void objectSyncTest(String name, int time) {
synchronized (lockObject) {
try {
System.out.println("objectSyncTest start: " + name);
Thread.sleep(1000*time);
System.out.println("objectSyncTest end: " + name);
} catch (InterruptedException e) {
}
}
}
public void thisSyncTest(String name, int time) {
synchronized (this) {
try {
System.out.println("thisSyncTest start: " + name);
Thread.sleep(1000*time);
System.out.println("thisSyncTest end: " + name);
} catch (InterruptedException e) {
}
}
}
public void classSyncTest(String name, int time) {
synchronized (SyncClass.class) {
try {
System.out.println("classSyncTest start: " + name);
Thread.sleep(1000*time);
System.out.println("classSyncTest end: " + name);
} catch (InterruptedException e) {
}
}
}
public void thisSyncTest2(String name, int time) {
synchronized (this) {
try {
System.out.println("thisSyncTest2 start: " + name);
Thread.sleep(1000*time);
System.out.println("thisSyncTest2 end: " + name);
} catch (InterruptedException e) {
}
}
}
public void thisSyncPartTest(String name, int time) {
synchronized (this) {
try {
System.out.println("thisSyncPartTest this start: " + name);
Thread.sleep(1000*2);
System.out.println("thisSyncPartTest this end: " + name);
} catch (InterruptedException e) {
}
}
try {
System.out.println("thisSyncPartTest start: " + name);
Thread.sleep(1000*time);
System.out.println("thisSyncPartTest end: " + name);
} catch (InterruptedException e) {
}
}
public synchronized void syncTest(String name, int time) {
try {
System.out.println("syncTest start: " + name);
Thread.sleep(1000*time);
System.out.println("syncTest end: " + name);
} catch (InterruptedException e) {
}
}
public synchronized void syncTest2(String name, int time) {
try {
System.out.println("syncTest2 start: " + name);
Thread.sleep(1000*time);
System.out.println("syncTest2 end: " + name);
} catch (InterruptedException e) {
}
}
public static synchronized void syncStaticTest(String name, int time) {
try {
System.out.println("syncStaticTest start: " + name);
Thread.sleep(1000*time);
System.out.println("syncStaticTest end: " + name);
} catch (InterruptedException e) {
}
}
public static synchronized void syncStaticTest2(String name, int time) {
try {
System.out.println("syncStaticTest2 start: " + name);
Thread.sleep(1000*time);
System.out.println("syncStaticTest2 end: " + name);
} catch (InterruptedException e) {
}
}
public static void staticTest(String name, int time) {
try {
System.out.println("staticTest start: " + name);
Thread.sleep(1000*time);
System.out.println("staticTest end: " + name);
} catch (InterruptedException e) {
}
}
public static void thisSyncStaticTest(String name, int time) {
synchronized (SyncClass.class) {
try {
System.out.println("thisSyncStaticTest start: " + name);
Thread.sleep(1000*time);
System.out.println("thisSyncStaticTest end: " + name);
} catch (InterruptedException e) {
}
}
}
}
public class ThreadTest {
static SyncClass staticSyncClass = new SyncClass();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Worker());
Thread thread2 = new Thread(new Worker());
thread1.setName("A");
thread2.setName("B");
thread1.start();
thread2.start();
}
private static class Worker implements Runnable {
@Override
public void run() {
String name = Thread.currentThread().getName();
if(name.equals("A")) {
try {
Thread.sleep(1000*1);
} catch (InterruptedException e) {
}
// SyncClass syncClass = new SyncClass();
// syncClass.thisSyncTest(name, 5);
}else if(name.equals("B")) {
// SyncClass syncClass = new SyncClass();
// syncClass.thisSyncTest(name, 5);
}
}
}
}
동시에 접근 가능
public void basic(String name) {
System.out.println("basic: " + name);
}
호출1
Thread별로 클래스를 생성 하였기 때문에 동시에 접근 가능하다.
호출2
1개의 Class를 공유해서 사용 -> 이전 결과와 다르게 B가 끝나야 A가 실행이 된다.
Class를 공유해서 사용하고 synchronized를 사용하면 다른 모든 synchronized도 lock이 걸림
public synchronized void syncTest(String name, int time) {
try {
System.out.println("syncTest: " + name);
Thread.sleep(1000*time);
} catch (InterruptedException e) {
}
}
//위와 동일하다
public void thisSyncTest(String name, int time) {
synchronized (this) {
try {
System.out.println("thisSyncTest start: " + name);
Thread.sleep(1000*time);
System.out.println("thisSyncTest end: " + name);
} catch (InterruptedException e) {
}
}
}
호출1
SyncClass syncClass = new SyncClass();
syncClass.syncTest(name, 10);
결과1
syncTest start: B
syncTest start: A
syncTest end: B
syncTest end: A
호출2
staticSyncClass.syncTest(name, 5);
결과2
syncTest start: B
syncTest end: B
syncTest start: A
syncTest end: A
static
호출1, 호출2를 보면 synchronized 메소드들은 동시에 접근이 되지 않는다.
호출3, 호출4를 보면 synchronized사용하지 않은 메소드는 바로 접근이 된다.
public static synchronized void syncStaticTest(String name, int time) {
try {
System.out.println("syncStaticTest start: " + name);
Thread.sleep(1000*time);
System.out.println("syncStaticTest end: " + name);
} catch (InterruptedException e) {
}
}
//위와 동일하다
public static void thisSyncStaticTest(String name, int time) {
synchronized (SyncClass.class) {
try {
System.out.println("thisSyncStaticTest start: " + name);
Thread.sleep(1000*time);
System.out.println("thisSyncStaticTest end: " + name);
} catch (InterruptedException e) {
}
}
}
public static synchronized void syncStaticTest2(String name, int time) {
try {
System.out.println("syncStaticTest2 start: " + name);
Thread.sleep(1000*time);
System.out.println("syncStaticTest2 end: " + name);
} catch (InterruptedException e) {
}
}
public static void staticTest(String name, int time) {
try {
System.out.println("staticTest start: " + name);
Thread.sleep(1000*time);
System.out.println("staticTest end: " + name);
} catch (InterruptedException e) {
}
}
public void basic(String name) {
System.out.println("basic: " + name);
}
호출1
SyncClass.syncStaticTest(name, 5);
결과1
syncStaticTest start: B
syncStaticTest end: B
syncStaticTest start: A
syncStaticTest end: A
호출2
Thread1: SyncClass.syncStaticTest2(name, 5);
Thread2: SyncClass.syncStaticTest(name, 5);
결과2
syncStaticTest start: B
syncStaticTest end: B
syncStaticTest start: A
syncStaticTest end: A
호출3
Thread1:
SyncClass syncClass = new SyncClass();
syncClass.basic(name);
Thread2: SyncClass.syncStaticTest(name, 5);
결과3
syncStaticTest start: B
basic: A
syncStaticTest end: B
호출4
Thread1: SyncClass.staticTest(name, 5);
Thread2: SyncClass.syncStaticTest(name, 5);
결과4
syncStaticTest start: B
staticTest start: A
syncStaticTest end: B
staticTest end: A
부분적으로.
synchronized 부분만 lock이 걸린다. 동일하게 class를 공유하여 사용 시에만 해당된다.
public void thisSyncPartTest(String name, int time) {
synchronized (this) {
try {
System.out.println("thisSyncPartTest this start: " + name);
Thread.sleep(1000*2);
System.out.println("thisSyncPartTest this end: " + name);
} catch (InterruptedException e) {
}
}
try {
System.out.println("thisSyncPartTest start: " + name);
Thread.sleep(1000*time);
System.out.println("thisSyncPartTest end: " + name);
} catch (InterruptedException e) {
}
}
호출1
staticSyncClass.thisSyncPartTest(name, 5);
결과1
thisSyncPartTest this start: B
thisSyncPartTest this end: B
thisSyncPartTest start: B <- synchronized 끝난 시점
thisSyncPartTest this start: A
thisSyncPartTest this end: A
thisSyncPartTest start: A
thisSyncPartTest end: B
thisSyncPartTest end: A
호출2
SyncClass syncClass = new SyncClass();
syncClass.thisSyncPartTest(name, 5);
결과2
thisSyncPartTest this start: B
thisSyncPartTest this start: A
thisSyncPartTest this end: B
thisSyncPartTest start: B
thisSyncPartTest this end: A
thisSyncPartTest start: A
thisSyncPartTest end: B
thisSyncPartTest end: A
this와 class 차이
Class를 사용하면 새로 생성해도 동시에 접근 못 한다.
What is the difference between synchronized(this) and synchronized(ClassName.class)?
I read somewhere that synchronized(this) should be avoided for various reasons. Yet some respectable code that I encountered uses the following in the constructor: public SomeClass(Context context...
stackoverflow.com
public void thisSyncTest(String name, int time) {
synchronized (this) {
try {
System.out.println("thisSyncTest start: " + name);
Thread.sleep(1000*time);
System.out.println("thisSyncTest end: " + name);
} catch (InterruptedException e) {
}
}
}
public void classSyncTest(String name, int time) {
synchronized (SyncClass.class) {
try {
System.out.println("classSyncTest start: " + name);
Thread.sleep(1000*time);
System.out.println("classSyncTest end: " + name);
} catch (InterruptedException e) {
}
}
}
호출1
SyncClass syncClass = new SyncClass();
syncClass.thisSyncTest(name, 5);
결과1
thisSyncTest start: B
thisSyncTest start: A
thisSyncTest end: B
thisSyncTest end: A
호출2
SyncClass syncClass = new SyncClass();
syncClass.classSyncTest(name, 5);
결과2
classSyncTest start: B
classSyncTest end: B
classSyncTest start: A
classSyncTest end: A
Object를 사용하는 방법도 있다. this하고 비슷하게 동작하는거 같고 검색 해보면 공격을 방지한다고 한다.
현재 내 코드에서는 비슷한 샘플을 만들 수 없을거 같다.
baeldung 여기에 좋은 샘플이 있다.
What is different between method synchronized vs object synchronized ?
Possible Duplicate: synchronized block vs synchronized method? If anyone can help me with real example about what is different between method synchronized vs object synchronized?, it would be ...
stackoverflow.com
https://www.baeldung.com/java-synchronization-bad-practices
private Object lockObject = new Object();
public void objectSyncTest(String name, int time) {
synchronized (lockObject) {
try {
System.out.println("objectSyncTest start: " + name);
Thread.sleep(1000*time);
System.out.println("objectSyncTest end: " + name);
} catch (InterruptedException e) {
}
}
}
'Lang > Java' 카테고리의 다른 글
윈도우 버전별 자바 최소 버전 (0) | 2024.05.25 |
---|---|
LocalDateTime 밀리세컨드 format 동적으로 처리방법 (0) | 2023.11.19 |
밀리세컨드 범위 동적으로 사용 (0) | 2023.05.07 |
LocalDateTime millisecond 계산 (0) | 2023.04.01 |
Quartz 간단하게 사용법 (0) | 2023.02.18 |