본문 바로가기

자바(JAVA)
[자바(Java)] 동기화

//★★Synchronized(동기화)

- 동기화된 메서드는 수많은 스레드 중 단 한 개의 스레드에서만 실행 가능 > thread safe

package com.sorrel012.com;

public class ConcurrencyRunner {

	public static void main(String[] args) {

		Counter counter = new Counter();
		counter.increment();
		counter.increment();
		counter.increment();
		System.out.println(counter.getI());

	} //main
	
}

 

package com.sorrel012.com;

public class Counter {
	
	private int i = 0;
	
	public int getI() {
		return i;
	}

	synchronized public void increment() {
		i++;
	}

}

 

- ★동기화는 overhead가 많이 생김.
    > 다른 코드를 실행해야 하는 스레드들이 무조건 대기를 해야 되기 때문

package com.sorrel012.com;

public class BiCounter {
	
	private int i = 0;
	private int j = 0;
	
	synchronized public void incrementI() {
		i++;
	}
	
	public int getI() {
		return i;
	}

	synchronized public void incrementJ() {
		j++;
	}
	
	public int getJ() {
		return j;
	}
}

// Lock

- synchronized의 문제점을 해결하기 위해 사용한다.

- 하나의 동기화된 커다란 코드를 갖고 있는 것이 아니라 여러 개의 작은 코드로 쪼갬으로써 thread가 해당 코드를 수행하는 동안 병렬 구조를 통해 다른 thread 또한 코드를  실행할 수 있다. > 유연성

- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;

- 선언 및 생성

Lock 변수명 = new ReentrantLock();


- 변수명.lock() : lock을 호출할 때 해당 lock을 갖는 다른 thread가 존재하지 않는다면 lock을 얻고 작업을 수행한다.

- 변수명.unlock() : 작업을 수행한 후 lock을 release한다.

-변수명.trylock() : lock을 이곳 저곳에서 사용할 수 있게 해준다.
    > lock을 사용하지 못하게 된다면, false 반환


package com.sorrel012.com;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BiCounterWithLock {
	
	private int i = 0;
	private int j = 0;
	
	Lock lockForI = new ReentrantLock();
	Lock lockForJ = new ReentrantLock();
	
	public void incrementI() {
		lockForI.lock(); //Get Lock For I
		i++;
		lockForI.unlock(); //Release Lock For I
	}
	
	public int getI() {
		return i;
	}

	public void incrementJ() {
		lockForJ.lock(); //Get Lock For J
		j++;
		lockForJ.unlock(); //Release Lock For J
	}
	
	public int getJ() {
		return j;
	}
	
}

 

package com.sorrel012.com;

public class ConcurrencyRunner {

	public static void main(String[] args) {

		BiCounterWithLock lock = new BiCounterWithLock();
		
		lock.incrementI();
		lock.incrementI();
		lock.incrementJ();
		lock.incrementI();
		
		System.out.println(lock.getI());
		System.out.println(lock.getJ());
		
	} //main
	
}

//AtomicInteger

- '자동 숫자 증가' 와 같은 응용 프로그램에서 lock 대신 간단하게 사용할 수 있다.

- import java.util.concurrent.atomic.AtomicInteger;

- 선언 및 생성

AtomicInteger 변수명 = new AtomicInteger();


- 변수명.incrementAndGet() : 숫자를 증가시켜준다.

- 변수명.decrementAndGet() : 숫자를 감소시켜준다.

- 변수명.Get() : 숫자를 반환한다.


package com.sorrel012.com;

import java.util.concurrent.atomic.AtomicInteger;

public class BiCounterWithAtomicInteger {
	
	private AtomicInteger i = new AtomicInteger();
	private AtomicInteger j = new AtomicInteger();
	
	
	public void incrementI() {
		i.incrementAndGet();
	}
	
	public void decrementI() {
		i.decrementAndGet();
	}
	
	public int getI() {
		return i.get();
	}

	public void incrementJ() {
		j.incrementAndGet();
	}
	
	public int getJ() {
		return j.get();
	}
	
}

 

package com.sorrel012.com;

public class ConcurrencyRunner {

	public static void main(String[] args) {

		BiCounterWithAtomicInteger atomic = new BiCounterWithAtomicInteger();
		
		atomic.incrementI();
		atomic.incrementI();
		atomic.incrementI();
		
		System.out.println(atomic.getI());

		
		atomic.decrementI();
		
		System.out.println(atomic.getI());
		
	} //main
	
}

// ConcurrentCollection

- 장황한 단계들을 거쳐야 하는 연산을 atomic 연산으로 변환해 준다.


- ConcurrentHashMap

package com.sorrel012.com;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.LongAdder;

public class ConcurrentMapRunner {
	
	public static void main(String[] args) {

		ConcurrentMap<Character, LongAdder> occurances = new ConcurrentHashMap<>();
		
		String str = "ABCD ABCD ABCD";
		
		for(char character:str.toCharArray()) {

			occurances.computeIfAbsent(character, ch -> new LongAdder()).increment();
		}

		System.out.println(occurances);

	} //main
}

'자바(JAVA)' 카테고리의 다른 글

[자바(Java)] static  (0) 2023.02.20
[자바(Java)] equals , hashcode  (0) 2023.02.19
[자바(Java)] 디버그(debug)  (0) 2023.02.09
[자바(Java)] 연산자  (0) 2023.02.06
[자바(Java)] DateTime  (0) 2023.02.06