9. μμΈ(Exception) μ λμμ±(λ©ν°μ€λ λ)
by JiwonDev# μμΈλ μ§μ§ μμΈμν©μμ μ¬μ©νλΌ.
μ μμ μΈ μλΉμ€ νλ¦μ μμΈλ₯Ό μ¬μ©νμ§ λ§λΌ.
try-catch λ¬Έμ JVMμ μ΅μ νλ₯Ό λ§μλ²λ¦¬κ³ νλ¦ μ μ΄μ μ°μΈ μμΈ λλ¬Έμ μ€μ λ²κ·Έκ° μ¨κ²¨μ Έμ λλ²κΉ μ΄ μ΄λ €μμ§λ€.
μ΄λ μ¬μ©μ(ν΄λΌμ΄μΈνΈ)μ μ μ₯μμ μκ°νλ©΄ μ½λ€. μλμ κ°μ μ½λλ₯Ό μκ°ν΄λ³΄μ.
for(Iterator<Foo> i = collection.iterator(); i.hasNext();){
Foo foo = i.next();
}
Iterator μΈν°νμ΄μ€μ next(), hasNext() λ©μλκ° μλ€λ©΄ μλμ κ°μ΄ μ¬μ©ν΄μΌ ν κ²μ΄λ€. μ΄λ μ’μ§ μλ€.
try{
Iterator<Foo> i = collection.iterator();
while(true)
Foo foo = i.next();
...
} catch (NoSuchElementException e){}
μμκ° μλ건 μ μμ μΈ λ‘μ§ νλ¦μ΄λ€. μ€λ₯λ μμΈμν©μ΄ μλλ€.
μμΈκ° λ°μνμ λλ μ λ§ μμΈ μν©μ΄ μΌμ΄λ¬μ λμ΄λ€. μ¬μ©μ(ν΄λΌμ΄μΈνΈ)μκ² νΌλμ μ£Όμ§ λ§λΌ.
π μνκ²μ¬ λ©μλ(.hasNext()μ²λΌ κ°μ λ°λ‘ λ°ννλ λ©μλ)μ μν μμ‘΄λ©μλ(.nextμ κ°μ΄ true, false μ²΄ν¬ μ©λ)
μν μμ‘΄λ©μλκ° μλκ² μ¬μ©νκΈ° ν¨μ¬ νΈνλ€.
νμ§λ§ μΈλΆ λκΈ°ν μμ΄ μ¬λ¬ μ€λ λκ° λμμ μ κ·Όν μ μκ±°λ, μ¬μ΄λ μ΄ννΈμ μ¬μ§κ° μλ€λ©΄ μν μμ‘΄λ©μλ μμ΄ κ°μ λ°λ‘ μ λ¬νκ±°λ Optionalλ±μ μ¬μ©νλκ² μ’λ€. κ·Έ μ κΉλμ κ°μ²΄μ μνκ° λ³ν μ μκΈ° λλ¬Έμ΄λ€.
# 볡ꡬν μ μλ€λ©΄ check μμΈλ₯Ό, μλλΌλ©΄ λ°νμ μμΈλ₯Ό λ°μμ¬μ©ν΄λΌ.
ν΄λΉ λ©μλλ₯Ό μ¬μ©(νΈμΆ)νλ μͺ½μμ 볡ꡬλ₯Ό ν΄μΌνλ€λ©΄ checked μμΈλ₯Ό μ¬μ©νλΌ.
κ·Έκ² μλλΌλ©΄ Runtime μμΈλ₯Ό λ°μμμΌ μ€λ₯μμ 빨리 μλ €λΌ. μμΈλ₯Ό κ°μΈ μμΈ λ΄μ©μ κ³μΈ΅μ λ§κ² μΆμννλ κ²λ μ’λ€. DB μμ SQL μλ¬κ° λκ±Έ, λΉμ¦λμ€ μλΉμ€μμ κ·Έλλ‘ μ λ¬νλ κ±° λ³΄λ€ 'μλΉμ€ λμ μ€λ₯'λ‘ μΆμν μν€μ.
2021.07.07 - [π±Backend/Java] - #7 Exception (μμΈμ²λ¦¬)
# νμμλ κ²μ¬ μμΈλ μ¬μ©μ νΌνλΌ.
κΌ μμΈλ₯Ό μ¬μ©νμ§ μμλ λλ λ©μλκ° μλ€. κ°λ₯νλ©΄ Optionalμ΄λ κ²μ¬ λ©μλ(true, false)λ₯Ό λ°ννκ² λ§λ€μ.
try{ // κΈ°μ‘΄ μ½λ
obj.action(args);
} catch(TheCheckedException e) {
...μμΈμν©μ λμ²νλ€.
}
if(obj.actionPermitted(args)){ // μμΈλ₯Ό μ¬μ©νμ§ μμ μ½λ
obj.action(args);
}else{
...μμΈμν©μ λμ²νλ€.
}
* λ¨ κ²μ¬λ©μλλ λ©ν°μ€λ λ νκ²½μ΄λ side-effectκ° μλ€λ©΄ μ¬μ©νμ§λ§κ³ , λ°λ‘ κ°μ΄λ Optionalμ λ°ννμ.
μ΄λ€ λ©μλκ° check μμΈλ₯Ό λμ§λ κ²μ, μ΄λ₯Ό νΈμΆνλ μ μ₯μμ catch λΈλμ λ§λ€μ΄ μμΈλ₯Ό μ²λ¦¬ν΄μΌνλ λΆλ΄μ΄ μκΈ΄λ€. λν Java8 λΆν° μ¬μ©νλ μ€νΈλ¦Όμμλ μμΈ λμ§λ λ©μλλ₯Ό μ¬μ©νκΈ° μ΄λ ΅λ€.
# νμ€ μμΈλ₯Ό μ¬μ©νλΌ.
μ¬μ¬μ©νκΈ° μ½κ³ , κ°λ μ±μ΄ μ’μΌλ©°, ν΄λμ€λ₯Ό μλ§λ€μ΄λ λμ μ±λ₯λ μ’μμ§λ€.
IllegalArgumentException | νμ©νμ§ μλ κ°μ΄ μΈμλ‘ μ λ¬ λ¬μ λ |
IllegalStateException | κ°μ²΄κ° λ©μλλ₯Ό μννκΈ° μ μ νμ§ μμ λ (μΈμκ°μ΄ 무μμ΄λ μ΄μ°¨νΌ μ€ν¨) |
NullPointerException | nullμ νμ©νμ§ μλ λ©μλμ nullμ 건λΈμ λ |
IndexOutOfBoundsException | μΈλ±μ€κ° λ²μλ₯Ό λμμ λ |
ConcurrentModificationException | νμ©νμ§ μλ λμ μμ μ΄ λ°κ²¬λ¬μ λ |
UnsupportedOperationException | νΈμΆν λ©μλλ₯Ό μ§μνμ§ μμλ |
λ€λ§ μμ μμΈ(Exception, RuntimeException, Throwable, Error)λ μ¬μ¬μ©νμ§λ§μ. μ΄λ€μ μΆμ ν΄λμ€μ²λΌ λ€λ₯Έ μμΈλ€μ ν¬ν¨νλ μμ ν΄λμ€μ΄λ―λ‘, μμ μ μΌλ‘ ν μ€νΈν μ μλ€. λ§μ½ μ μ ν νμ€ μμΈκ° μλ€λ©΄ μμλ°μ μλ‘κ² λ§λ€μ.
μ°Έκ³ λ‘ IllegalArgumentException κ³Ό IllegalStateExceptionμ΄ ν·κ°λ¦΄ μ μλλ°, μΈμ κ°μ΄ 무μμ΄λ μ΄μ°¨νΌ μ€ν¨νμ κ±°λΌλ©΄ Stateλ₯Ό μ¬μ©νλ©΄ λλ€. μλλΌλ©΄ Argument.
# μΆμν μμ€μ λ§λ μμΈλ₯Ό λμ ΈλΌ.
λΉμ¦λμ€ μλΉμ€λ¨μμ low-levelμ λ©λͺ¨λ¦¬ μμΈκ° λμ¨λ€λ©΄ λ§€μ° λΉν©μ€λ½κ³ , μ²λ¦¬ν λ°©λ²λ μλ€.
μ μμ€μ μμΈλ₯Ό μ‘μμ μλ‘μ΄ μμΈλ‘ μΆμν μμΌλΌ. λλ²κΉ μ λμμ΄ λλ€λ©΄ μμΈ chainμ λ§λλκ² μ’λ€.
try{
} catch(LowerLevelException e){
throw new HigherLevelException();
}
try{
} catch(LowerLevelException e){
throw new HigherLevelException(e); // μ΄λ κ² κ°μΈλ κ²λ μ’μλ°©λ². μμΈμ κ·Όλ³Έ μμΈμ μ°Ύμ μ μλ€.
}
class HigherLevelException extends Exception {
HigherLevelException(Throwable throwable){
super(throwable);
}
}
# λ©μλκ° λμ§λ μμΈλ λͺ¨λ λ¬Έμνν΄λΌ.
λ©μλκ° λμ§ κ°λ₯μ±μ΄ μλ μμΈλ λͺ¨λ λ¬Έμννλκ² μ’λ€. μΆμ λ©μλλ, λ°νμ λ©μλλ λ§μ°¬κ°μ§μ΄λ€.
@throws λλ @Exception νκ·Έλ₯Ό νμ©νμ. μ°Έκ³ λ‘ μ΄ λκ°μ κΈ°λ₯μ κ°λ€.
public class Sample {
/**
* νμΌ μ°κΈ°
*
* @throws FileNotFoundException μ§μ λ νμΌμ μ°Ύμ μ μμ΅λλ€
*/
public void writeToFile() throws FileNotFoundException {
}
/**
* νμΌ μ½κΈ°
*
* @throws java.io.IOException μ
μΆλ ₯ κ΄λ ¨
* @throws java.lang.SecurityException 보μ κ΄λ ¨
*/
public void readFromFile() throws IOException, java.lang.SecurityException {
}
}
μμΈ μμΈλ©μμ§μ μ€ν¨ κ΄λ ¨ μ 보λ₯Ό λ΄μΌλ©΄ λ μ’λ€.
// java9μμλ IndexOutOfBoundsλ indexλ₯Ό λ°λλ‘ μΆκ°λμλ€. μμ½κ²λ lower, upperλ μμ.
public IndexOutOfBoundsException(int lowerBound, int upperBound, int index) {
super(String.format("μ΅μκ°: %d, μ΅λκ°: %d, μΈλ±μ€: %d", lowerBound, upperBound, index))
this.lowerBound = lowerBound;
this.uppperBound = upperBound;
this.index = index;
}
* λ¨ μμΈμ 보μκ³Ό κ΄λ ¨λ μ 보(κ³μ λ±)λ μ£Όμν΄μ λ€λ€μΌνλ€. μ€ν μΆμ μ 보λ λ§μ μ¬λμ΄ λ³Ό μ μκΈ° λλ¬Έμ΄λ€.
# κ°λ₯νλ©΄ μ€ν¨ μμμ μΌλ‘ λ§λ€μ΄λΌ.
μμΈκ° λ°μνλ€λ©΄, λ°μνκΈ° μ μν©μ μ μ§νλλ‘ λ§λ€μ΄λΌ.
μΌλ¨ μμ νκ³ λ¬Έμ κ° μλ€λ©΄ μμΈλ₯Ό λ°μμν€λ κ² λ³΄λ€ λ¨Όμ κ²μ¬λ₯Ό νκ³ μμ νλκ² μ’λ€.
public Object pop() {
if(size == 0) //λ©μλλ₯Ό μ¬μ©νκΈ°μ 맀κ°λ³μμ μ ν¨μ±μ κ²μ¬νμ¬ μ€ν¨ν κ²½μ°,μν λ³κ²½μ λ§λλ€!
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null;
return result;
}
μ΄κ² νλ€λ€λ©΄ κ°μ²΄μ μμ 볡μ¬λ³Έμμ μμ μ μνν λ€μ, μ±κ³΅νμ λ μ€μ κ°μ²΄μ κ΅μ²΄νλ λ°©λ²λ μλ€.
λ¬Όλ‘ μ΄λ κ² νμ§μκ³ λ°λ‘ 볡ꡬ μ½λλ₯Ό μμ±νμ¬ μμ νκΈ° μ μνλ‘ λ리λ λ°©λ²λ μμ§λ§, μ’μ λ°©λ²μ μλλ€.
# μμΈλ₯Ό 무μνμ§ λ§λΌ.
λ»ν μ΄μΌκΈ° κ°μ§λ§, μ’ μ’ μΌμ΄λλ μΌμ΄λ€.
// catch λΈλ‘μ λΉμλλ©΄ μμΈκ° 무μλλ€. μμ£Ό μμ¬μ€λ¬μ΄ μ½λλ€!
try {
...
} catch (SomeException e) {
//μ무 μΌλ νμ§ μμ.
}
μ΄λ° μ½λλ μ€μ μμΈκ° λ°μνμ λ, μ΄λ₯Ό μ¨κ²¨λ²λ € λλ²κΉ μ λ§€μ° μ΄λ ΅κ² λ§λ λ€. μ¬ν κ²½μ° μ€λ₯λ₯Ό μ²λ¦¬νμ§ μκ³ ν¬ν¨ν μ±λ‘ μ±μ΄ λμνλ€κ° λ¬Έμ μ μμΈμ μ ν λͺ¨λ₯΄λ μνλ‘ κ°μκΈ° μ±μ΄ μ£½μ΄λ²λ¦΄ μ μλ€.
μ λ§ νΉμν κ²½μ°λΌμ μμΈκ° νμμλ€λ©΄, κ·Έ μ΄μ λ₯Ό μ£ΌμμΌλ‘ λ¨κΈ°κ³ μμΈ λ³μμ μ΄λ¦μ ignored λ±μΌλ‘ λͺ μμ μΌλ‘ λ°μ λνλ΄μ. λν λ‘κ·Έλ₯Ό νμ©ν΄ μ΅μνμ λλ²κΉ μ 보λ₯Ό λ¨κΈ°μ.
# 곡μ μ€μΈ λ°μ΄ν°λ λκΈ°νκ° νμμ΄λ€. (λΆλ³ λ°μ΄ν°μΈ κ²½μ°λ νμμμ)
μ΄μ체μ λ₯Ό λ°°μ λ€λ©΄ μκ² μ§λ§, μ¬λ¬ μ€λ λκ° λμμ κ°μ μ½κ³ μμ νλ건 λ§€μ° μνν νμμ΄λ€.
μ¬μ§μ΄ λκΈ°νμμ λ°μν λ²κ·Έλ λλ²κΉ λμ΄λκ° λμνΈμ΄λ€. κ°νμ μΌλ‘ λ°μνκ±°λ, νΉμ νμ΄λ°μλ§ λ°μνκ³ VMμ μ΅μ νμ λ°λΌ λ€λ₯΄κ² λμνκΈ°λ νκΈ° λλ¬Έμ΄λ€.
# κ³Όλν λκΈ°νλ νΌνλΌ
λκΈ°νλ μ€λ λλ₯Ό λΈλ¬νΉνμ¬ μ±λ₯μ μ¬νκ² λ¨μ΄λ¨λ¦¬κ³ , κ΅μ°©μνμ λΉ νΈλ¦°λ€.
κΌ νμν κ³³μλ§ μ¬μ©νμ. synchronziedλ λ©μλλ¨μκ° μλ, { ~ } λΈλ λ¨μλ‘λ μ¬μ©ν μ μλ€.
κ³Όλν λκΈ°νλ λ³λ ¬λ‘ μ€νν κΈ°νλ₯Ό μκ³ , λͺ¨λ μ½μ΄κ° λ©λͺ¨λ¦¬λ₯Ό μΌκ΄λκ² λ³΄κΈ° μν μ§μ°μκ°(λΈλ‘νΉ)μ΄ μ§μ§ λΉμ©μ΄λ€. λν JVMμ μ½λ μ΅μ νλ₯Ό μ ννλ κ²λ κ³ λ €ν΄μΌ νλ€.
λ°λΌμ κ°λ³ ν΄λμ€λ₯Ό μμ±ν λλ λ κ°μ§ μ νμ ν μ μλ€.
첫 λ²μ§Έλ λκΈ°νλ₯Ό νμ§ μκ³ , κ·Έ ν΄λμ€λ₯Ό μ¬μ©ν΄μΌ νλ ν΄λμ€κ° μΈλΆμμ λκΈ°ννλ κ²μ΄λ€.
λ λ²μ§Έλ λκΈ°νλ₯Ό λ΄λΆμμ μνν΄ thread-safe ν ν΄λμ€λ‘ λ§λλ κ²μ΄λ€. λ€λ§ ν΄λΌμ΄μΈνΈκ° μΈλΆμμ κ°μ²΄ μ 체μ λ½μ κ±°λ κ²λ³΄λ€ λμμ±μ κ°μ ν μ μμ λ μ νν΄μΌ νλ€. μλ‘λ java.util.concurrent ν¨ν€μ§κ° μλ€.
java.util.Randomλ λ§μ°¬κ°μ§λ€. λκΈ°ννμ§ μλ λ²μ μΈ ThreadLocalRandomμΌλ‘ λ체λμλ€.
μ ννκΈ° μ΄λ ΅λ€λ©΄ λκΈ°ννμ§ λ§κ³ , λμ λ¬Έμμ “μ€λ λ μμ νμ§ μλ€” κ³ λͺ μνμ.
# μ€λ λλ₯Ό μ§μ λ§λ€μ§λ§κ³ μ€νμ, ν μ€ν¬, μ€νΈλ¦Όμ μ΄μ©νλΌ.
μ€λ λλ₯Ό μ§μ λ€λ£° μ μμ§λ§ concurrent ν¨ν€μ§λ₯Ό μ΄μ©νλ©΄ κ°λ¨νκ² μ½λλ₯Ό μμ±ν μ μλ€.
μ΄λ μ¬μ©μ± λΏλ§μλλΌ μμ λ¨μμ μ€ν 맀컀λμ¦μ λΆλ¦¬νλ ν¨κ³Όλ μλ€.
java.util.concurrent ν¨ν€μ§ μμλ μ€νμ νλ μμν¬(Executor Framework)κ° μλ€.
// νλ₯Ό μμ±νλ€.
ExecutorService exec = Executors.newSingleThreadExecutor();
// νμ€ν¬ μ€ν
exec.execute(runnable);
// μ€νμ μ’
λ£
exec.shutdown();
# μ€λ λ μμ μ± μμ€μ λ¬Έμνν΄λΌ.
λ°ν νμ λ§μΌλ‘ μ νν μ μμλ€λ©΄, (ν©ν 리 λ©μλ) μλ μ²λΌ μμ μ΄ λ°ννλ κ°μ²΄μ λν μ€λ λ μμ μ±μ λ¬Έμννλ κ²μ΄ μ’λ€. λ¨μν synchronized ν€μλκ° λΆμλ€κ³ ν΄μ, λͺ¨λ μν©μμ μμ νλ€λ 보μ₯μ ν μ μκΈ° λλ¬Έμ΄λ€.
Collections.synchronziedMap μ API λ¬Έμμλ μλμ κ°μ΄ λͺ μλμ΄ μλ€.
/**
* It is imperative that the user manually synchronize on the returned
* map when iterating over any of its collection views
* λ°νλ 맡μ μ½λ μ
λ·°λ₯Ό μνν λ λ°λμ κ·Έ 맡μΌλ‘ μλ λκΈ°ννλΌ
*
* Map m = Collections.synchronizedMap(new HashMap());
* ...
* Set s = m.keySet(); // Needn't be in synchronized block
* ...
* synchronized (m) { // Synchronizing on m, not s!
* Iterator i = s.iterator(); // Must be in synchronized block
* while (i.hasNext())
* foo(i.next());
* }
*/
- λΆλ³(immutable)
- β‘ ν΄λΉ ν΄λμ€μ μΈμ€ν΄μ€λ λ§μΉ μμμλ κ°μμ μΈλΆ λκΈ°νλ νμ μμ΅λλ€.
- β‘ μλ₯Ό λ€λ©΄ String, Long, BigInteger
- 무쑰건μ μΈ μ€λ λ μμ (unconditionally thread-safe)
- β‘ ν΄λΉ ν΄λμ€μ μΈμ€ν΄μ€λ μμ λ μ μμ§λ§ λ΄λΆμμλ μΆ©μ€ν λκΈ°ννμ¬ λ³λμ μΈλΆ λκΈ°νμμ΄ λμμ μ¬μ©ν΄λ μμ ν©λλ€.
- β‘ μλ₯Ό λ€λ©΄ AtomicLong, ConcurrentHashMap
- μ‘°κ±΄λΆ μ€λ λ μμ (conditionally thread-safe)
- ①무쑰건μ μΈ μ€λ λ μμ μ±κ³Ό κ°μ§λ§ μΌλΆ λ©μλλ λμμ μ¬μ©νλ €λ©΄ μΈλΆ λκΈ°νκ° νμν©λλ€.
- β‘ Collections.synchronized λνΌ λ©μλκ° λ°νν 컬λ μ
- μ€λ λ μμ νμ§ μμ(not thread-safe)
- β‘ ν΄λΉ ν΄λμ€μ μΈμ€ν΄μ€λ μμ λ μ μμΌλ©° λμμ μ¬μ©νλ €λ©΄ κ°κ°μ λ©μλ νΈμΆμ ν΄λΌμ΄μΈνΈκ° μ νν μΈλΆ λκΈ°ν λ‘μ§μΌλ‘ κ°μΈμΌ νλ€.
- β‘ μλ₯Ό λ€λ©΄ ArrayList, HashMap
- μ€λ λ μ λμ (thread-hostile)
- β‘ μΈλΆ λκΈ°νλ‘ κ°μΈλλΌλ λ©ν°μ€λ λ νκ²½μμ μμ νμ§ μμ΅λλ€.
- β‘ μ΄λ¬ν ν΄λμ€λ λμμ±μ κ³ λ €νμ§ μκ³ λ§λ€λ€λ³΄λ©΄ μ°μ°ν λ§λ€μ΄μ§λλ€.
# μ§μ° μ΄κΈ°νλ μ μ€ν μ¬μ©νλΌ.
λ°λλ‘ λ§νλ©΄ κΌ νμνκΈ° μ κΉμ§λ μ¬μ©νμ§ λ§λΌλ κ±°λ€. μ§μ° μ΄κΈ°νλ μλ μ κ²μ΄λ€.
μ΄κΈ°νμ λλ λΉμ©, μ΄κΈ°νλ νλμ νΈμΆ λΉλμμ λ°λΌ μ§μ° μ΄κΈ°νκ° μ€νλ € μ±λ₯μ μ νμν¬ μ μλ€. ν¬κ² νμν μν©μ΄ μλλΌλ©΄, μΌλ°μ μΈ μ΄κΈ°νκ° ν¨μ¬ λ«λ€.
// μΌλ°μ μΈ μΈμ€ν΄μ€ νλ μ΄κΈ°ν λ°©λ²
private final FieldType field = computeFieldValue();
public MyClass{
private static FieldType getField() {
return FieldHolder.field;
}
private static class FieldHolder {
static final FieldType field = computeFieldValue();
}
}
# νλ‘κ·Έλ¨μ λμμ μ€λ λ μ€μΌμ₯΄λ¬μ κΈ°λμ§ λ§λΌ.
μ€μΌμ₯΄λ¬ μ μ± μ μ΄μ체μ λ§λ€ λ€λ₯Ό μ μλ€. Thread.yield(λ€λ₯Έ μ€λ λμκ² μ€νμ μ보νλ λ©μλ) μ²λΌ μ€λ λ μ°μ μμλ₯Ό λ°κΎΈλ건 μ€μΌμ₯΄λ¬μ μ 곡νλ 'ννΈ' μΌ λΏμ΄μ§, λ°λμ κ·Έλ κ² λμν κ±°λΌλ 보μ₯μ μλ€. μλ°μ μ€λ λ μ°μ μμλ μ΄μ체μ μ΄μμ±μ΄ λμνΈμ΄λ€.
λν μ€λ λλ μ λλ‘ busy-waiting ν μνκ° λλ©΄ μλλ€. ν΄λΉ μ€λ λ λλ¬Έμ μ± μ 체μμ λ€λ₯Έ μ μ©ν μμ μ΄ μ€νλ κΈ°νκ° λ°νλ¨μ μΈμ§νκ³ μμ.
// Busy-waiting μ½λ. μ§κΈ μλν΄λ λλμ§ μ¬λΆλ₯Ό κ³μν΄μ μ€λ λκ° μ€μ€λ‘ κ²μ¬ν¨.
public class SlowCountDownLatch {
private int count;
public SlowCountDownLatch(int count) {
if (count < 0)
throw new IllegalArgumentException(count + " < 0");
this.count = count;
}
public void await() {
while (true) { // μ§μ§ μ΄λ κ² ν 건κ°?
synchronized(this) {
if (count == 0)
return;
}
}
}
public synchronized void countDown() {
if (count != 0)
count--;
}
}
'π±Backend > Effective-Java' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
10. μ§λ ¬ν (0) | 2021.10.06 |
---|---|
8. μΌλ°μ μΈ νλ‘κ·Έλλ° μμΉ (0) | 2021.10.06 |
7. λλ€μ μ€νΈλ¦Ό, λ©μλ (0) | 2021.10.06 |
6-1 Enumκ³Ό @μ λν μ΄μ μ μ¬μ©νλΌ. (0) | 2021.10.06 |
5-2 μ λ€λ¦, λ°°μ΄λ³΄λ€λ 리μ€νΈλ₯Ό μ¬μ©νλΌ, (+μνΌνμ ꡬνλ°©λ²) (0) | 2021.09.15 |
λΈλ‘κ·Έμ μ 보
JiwonDev
JiwonDev