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 |