Skip to content

Commit

Permalink
Merge pull request #350 from Flamme1004K/item79
Browse files Browse the repository at this point in the history
[#79][2๊ธฐ] ๊ณผ๋„ํ•œ ๋™๊ธฐํ™”๋Š” ํ”ผํ•˜๋ผ.
  • Loading branch information
ksy90101 authored Oct 16, 2021
2 parents 87577e0 + 92ca67a commit d2578ec
Showing 1 changed file with 171 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# Item79 ๊ณผ๋„ํ•œ ๋™๊ธฐํ™”๋Š” ํ”ผํ•˜๋ผ

์‘๋‹ต ๋ถˆ๊ฐ€์™€ ์•ˆ์ „ ์‹คํŒจ๋ฅผ ํ”ผํ•˜๋ ค๋ฉด ๋™๊ธฐํ™” ๋ฉ”์„œ๋“œ๋‚˜ ๋™๊ธฐํ™” ๋ธ”๋ก ์•ˆ์—์„œ๋Š” ์ œ์–ด๋ฅผ ์ ˆ๋Œ€๋กœ ํด๋ผ์ด์–ธํŠธ์— ์–‘๋„ํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

### ์—ฌ๊ธฐ์„œ ์ œ์–ด๋ž€ ?
- ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ
- ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋„˜๊ฒจ์ค€ ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ํ˜ธ์ถœ

--> ์ด๋Ÿฌํ•œ ๋™๊ธฐํ™” ๋ฉ”์„œ๋‚˜ ๋ฐ ๋™๊ธฐํ™” ๋ธ”๋ก์— ๋Œ€ํ•œ ์ œ์–ด๋Š” ๊ณผ๋„ํ•œ ๋™๊ธฐํ™”๋ฅผ ์ผ์œผํ‚ด.

- ์„ฑ๋Šฅ์„ ๋–จ์–ดํŠธ๋ฆผ.
- ๊ต์ฐฉ์ƒํƒœ์— ๋น ํŠธ๋ฆผ.
- ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋Š” ๋™์ž‘์„ ๋‚ณ๊ธฐ๋„ ํ•œ๋‹ค.
- ๋ฐ์ดํ„ฐ๋ฅผ ํ›ผ์† ํ•  ์ˆ˜ ์žˆ์Œ.

---
public class ObservableSet<E> Extends ForwardingSet<E> {
public ObservableSet(Set<E> set) {super(set);}
public void addObserver(SetObserver<E> observer) {
synchronized(observer) {
observers.add(observer);
}
}
public boolean removeObserver(SetObserver<E> observer) {
synchronized(observers) {
return observers.remove(observer);
}
}

private void notifyElementAdded(E element) {
synchronized(observers) {
for (SetObserver<E> sbserver : observers)
observer.added(this, element);
}
}
}
@Override
public boolean add(E element) {
boolean added = super.add(element);
if (added)
notifyElementAdded(element);
return added;
}
@Override
public booleand addAll(Collection<? extends E> c) {
booleand result = false;
for (E element : c)
result = add(element);
return result;
}
}
---

1. ๊ด€์ฐฐ์ž๋“ค์€ addOverserver์™€ removeObserver ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด ๊ตฌ๋…์„ ์‹ ์ฒญํ•˜๊ฑฐ๋‚˜ ํ•ด์ง€ํ•œ๋‹ค.
2. ๋‘ ๊ฒฝ์šฐ ๋‹ค์Œ ์ฝœ๋ฐฑ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฉ”์„œ๋“œ์— ๊ฑด๋„จ๋‹ค.

---

@FuntionalInterface
public interface SetObserver<E> {
void added(ObservableSet<E> set, E element);
}

ํ•ด๋‹น ObserverSet์€ ์ž˜ ์ž‘๋™ํ•  ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ํ•œ๋‹ค.

---

public static void main(String[] args) {
ObservableSet<Integer> set = new ObservableSet<>(new HashSet<>());
set.addObserver((s,e) -> System.out.println(e));
for (int i = 0; i< 100; i++)
set.add(i);
}

์—ฌ๊ธฐ์„œ๋„ 0~99๊นŒ์ง€ ์ถœ๋ ฅ์„ ํ•œ๋‹ค.

---

set.addObserver(new SetObserver<>() {
public void added(ObservableSet<Ineger> s, Integer e) {
System.out.println(e);
if (e == 23)
s.removeObserver(this);
}
}
ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ 23์ด๋ฉด ์ž๊ธฐ ์ž์‹ ์„ ์ œ๊ฑฐํ•˜๋Š” ๊ด€์ฐฐ์ž๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด์ž.
์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

0~23๊นŒ์ง€ ์ถœ๋ ฅํ•œ ํ›„ ๊ด€์ฐฐ์ž ์ž์‹ ์„ ๊ตฌ๋…ํ•ด์ง€ํ•œ ๋‹ค์Œ ์กฐ์šฉํžˆ ์ข…๋ฃŒํ•  ๊ฒƒ์ด๋‹ค๋ผ๊ณ  ํ•˜์ง€๋งŒ,
์‹ค์ œ๋กœ ๊ทธ๋ ‡์ง€๋Š” ์•Š๊ณ . ๋ฐ”๋กœ ConcurrentModificationException์„ ๋˜์ง„๋‹ค.
์™œ๊ทธ๋Ÿด๊นŒ? ๊ทธ ์ด์œ ๋Š” ๋ฆฌ์ŠคํŠธ์—์„œ ์›์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๋ ค ํ•˜๋Š”๋ฐ, ์ด๋•Œ ์ด ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜๋Š” ๋„์ค‘์ด๋ผ, ํ—ˆ์šฉ์„ ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค.

notifyElementAdded ๋ฉ”์„œ๋“œ์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ์ˆœํšŒ๋Š” ๋™๊ธฐํ™” ๋ธ”๋ก ์•ˆ์— ์žˆ์œผ๋ฏ€๋กœ ๋™์‹œ ์ˆ˜์ •์ด ์ผ์–ด๋‚˜์ง€ ์•Š๋„๋ก ๋ณด์žฅํ•˜์ง€๋งŒ ์ •์ž‘ ์ž์‹ ์ด ์ฝœ๋ฐฑ์„ ๊ฑฐ์ณ ๋˜๋Œ์•„์™€ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๊นŒ์ง€ ๋ง‰์ง€๋Š” ๋ชปํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

---

set.addObserver(new SetObserver<> {
public void added(ObservableSet<Integer> s, Integer e) {
System.out.println(e);
if (e == 23) {
ExecutorService exec = Excutors.newSingleThreadExcutor();
try (
exec.submit(() -> s.removeObserver(this)).get();
} catch (ExcutionException | InterruptedException ex) {
throw new AssertionError(ex);
} finally {
exec.shutdown();
}
}
}
}

ํ•ด๋‹น ์˜ˆ์ œ์—์„œ๋Š”
1. ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ๊ฐ€ s.removeObserver๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ด€์ฐฐ์ž๋ฅผ ์ž ๊ทธ๋ ค ์‹œ๋„ํ•˜์ง€๋งŒ ๋ฝ์„ ์–ป์„ ์ˆ˜ ์—†๋‹ค๊ณ  ํ•œ๋‹ค. ๋ฐ”๋กœ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ด๋ฏธ ๋ฝ์„ ์ฅ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๊ณ  ํ•œ๋‹ค.
2. ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ, ๊ทธ์™€ ๋™์‹œ์— ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ด€์ฐฐ์ž๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ๋งŒ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ๊ต์ฐฉ ์ƒํƒœ๊ฐ€ ์ผ์–ด๋‚œ๋‹ค๊ณ  ํ•œ๋‹ค.

---

์–ด๋–ป๊ฒŒ ๋ฆฌํŒฉํ† ๋ง์„ ํ•ด์•ผํ• ๊นŒ?

๋ฐ”๋กœ

private void notifyElementAdded(E element) {
List<SetObserver<E>> snapshot = null;
synchronized(observers) {
sanpShot new ArrayList<>(Observers);
}
for (SetObserver<E> sbserver : observers)
observer.added(this, element);
}
}

๋™๊ธฐํ™” ๋ธ”๋ก ๋ฐ”๊นฅ์œผ๋กœ ์˜ฎ๊ธฐ๋ฉด ๋œ๋‹ค๊ณ  ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ์˜ฎ๊ฒจ๋ฒ„๋ฆฌ๋ฉด, ๋ฝ ์—†์ด๋„ ์•ˆ์ „ํ•˜๊ธฐ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•˜๋ฉฐ, ์˜ˆ์™ธ ๋ฐœ์ƒ๊ณผ ๊ต์ฐฉ์ƒํƒœ ์ฆ์ƒ์ด ์‚ฌ๋ผ์ง„๋‹ค๊ณ  ํ•œ๋‹ค.



# ์–ด๋–ป๊ฒŒ ๋™๊ธฐํ™”๋ฅผ ํ•ด์•ผํ•˜๋Š” ๊ฑธ๊นŒ?

1. ๋™๊ธฐํ™”๋ฅผ ์ „ํ˜€ ํ•˜์ง€ ๋ง๊ณ , ๊ทธ ํด๋ž˜์Šค๋ฅผ ๋™์‹œ์— ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ์™ธ๋ถ€์—์„œ ์•Œ์•„์„œ ๋™๊ธฐํ™”ํ•˜๊ฒŒ ํ•˜์ž.
2. ๋™๊ธฐํ™”๋ฅผ ๋‚ด๋ถ€์—์„œ ์ˆ˜ํ–‰ํ•ด ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•œ ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค์ž.

**์ฒซ๋ฒˆ ์งธ ๋ฐฉ์‹**์€ java.util(Vector์™€ HashTable์„ ์ œ์™ธ) ํƒํ•˜์˜€๊ณ ,
**๋‘๋ฒˆ ์งธ ๋ฐฉ์‹**์€ Java.util.concurrent๋ฅผ ํƒํ•˜์˜€๋‹ค. ๋‹จ, ๋‘๋ฒˆ ์งธ ๋ฐฉ์‹์€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์™ธ๋ถ€์—์„œ ๊ฐ์ฒด ์ „์ฒด์— ๋ฝ์„ ๊ฑฐ๋Š” ๊ฒƒ๋ณด๋‹ค ๋™์‹œ์„ฑ์„ ์›”๋“ฑํžˆ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์„ ๋•Œ ์„ ํƒํ•ด์•ผํ•œ๋‹ค.

์ž๋ฐ”๋Š” ์ดˆ์ฐฝ๊ธฐ์—๋Š” ์ด ์ง€์นจ์„ ๋”ฐ๋ฅด์ง€ ์•Š์•˜๋‹ค๊ณ  ํ•œ๋‹ค.

StringBuffer ์ธ์Šคํ„ด์Šค๋Š” ๊ฑฐ์˜ ํ•ญ์ƒ ๋‹จ์ผ ์“ฐ๋ ˆ๋“œ์—์„œ ์“ฐ์˜€์Œ์—๋„ ๋‚ด๋ถ€์ ์œผ๋กœ ๋™๊ธฐํ™”๋ฅผ ์ˆ˜ํ–‰ํ•˜์˜€๋‹ค. ์ด๋กœ ์ธํ•ด, ๋™๊ธฐํ™”๋ฅผ ํ•˜์ง€ ์•Š๋Š” StringBuilder๊ฐ€ ๋งŒ๋“ค์–ด ์กŒ๋‹ค.

๋น„์Šทํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ java.util.Random์€ ๋™๊ธฐํ™”ํ•˜์ง€ ์•Š๋Š” ๋ฒ„์ „์ธ java.util.concurrent.ThreadLocalRandom์œผ๋กœ ๋Œ€์ฒด๋˜์—ˆ๋‹ค.

๋งŒ์•ฝ ๋‘๊ฐœ๊ฐ€ ํž˜๋“ค๋‹ค๋ฉด, ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜์ง€ ์•Š๋‹ค๊ณ  ๋ช…๊ธฐํ•˜์ž.

3. ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ํ˜ธ์ถœํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์  ํ•„๋“œ๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค๋ฉด ๊ทธ ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋ฐ˜๋“œ์‹œ ๋™๊ธฐํ™”๋ฅผ ํ•ด์•ผ ํ•œ๋‹ค.

์ •์  ํ•„๋“œ๊ฐ€ ์‹ฌ์ง€์–ด pirvate๋ผ๋„ ์„œ๋กœ ๊ด€๋ จ ์—†๋Š” ์Šค๋ ˆ๋“œ๋“ค์ด ๋™์‹œ์— ์ฝ๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฉด, ์‚ฌ์‹ค์ƒ ์ „์—ญ ๋ณ€์ˆ˜์™€ ๊ฐ™์•„์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

## ๊ฒฐ๋ก 

- ๊ต์ฐฉ์ƒํƒœ์™€ ๋ฐ์ดํ„ฐ ํ›ผ์†์„ ํ”ผํ•˜๋ ค๋ฉด ๋™๊ธฐํ™” ์˜์—ญ ์•ˆ์—์„œ ์™ธ๊ณ„์ธ ๋ฉ”์„œ๋“œ๋ฅผ ์ ˆ๋Œ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์–‘๋„ํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

- ๋™๊ธฐํ™” ์˜์—ญ ์•ˆ์—์„œ์˜ ์ž‘์—…์€ ์ตœ์†Œํ•œ์œผ๋กœ ์ค„์ด์ž. ๊ฐ€๋ณ€ ํด๋ž˜์Šค๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ๋Š” ์Šค์Šค๋กœ ๋™๊ธฐํ™”ํ•ด์•ผ ํ• ์ง€ ๊ณ ๋ฏผํ•˜์ž.

- ๋ฉ€ํ‹ฐ์ฝ”์–ด ์„ธ์ƒ์ธ ์ง€๊ธˆ์€ ๊ณผ๋„ํ•œ ๋™๊ธฐํ™”๋ฅผ ํ”ผํ•˜๋Š” ๊ฒŒ ๊ณผ๊ฑฐ ์–ด๋Š ๋•Œ๋ณด๋‹ค ์ค‘์š”ํ•˜๋‹ค.

- ํ•ฉ๋‹นํ•œ ์ด์œ ๊ฐ€ ์žˆ์„ ๋•Œ๋งŒ ๋‚ด๋ถ€์—์„œ ๋™๊ธฐํ™”ํ•˜๊ณ , ๋™๊ธฐํ™”ํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฌธ์„œ์— ๋ช…ํ™•ํžˆ ๋ฐํžˆ์ž.

0 comments on commit d2578ec

Please sign in to comment.