νλ‘μΈμ€μ μ€λ λ
νλ‘μΈμ€ : μ€ν μ€μΈ μ ν리μΌμ΄μ . μ ν리μΌμ΄μ μ μ€ννλ©΄ μ΄μ체μ λ‘λΆν° μ€νμ νμν λ§νΌμ λ©λͺ¨λ¦¬λ₯Ό ν λΉλ°μ νλ‘μΈμ€κ° λλ€.
νλ‘μΈμ€λ λ°μ΄ν°, μ»΄ν¨ν° μμ, μ€λ λλ‘ κ΅¬μ±λλλ°, μ€λ λλ λ°μ΄ν°μ μ ν리μΌμ΄μ μ΄ ν보ν μμμ νμ©νμ¬ μμ€ μ½λλ₯Ό μ€ννλ€.
μ¦, μ€λ λλ νλμ μ½λ μ€ν νλ¦μ΄λΌκ³ λ³Ό μ μλ€.
λ©μΈ μ€λ λ
μλ° μ ν리μΌμ΄μ μ μ€ννλ©΄ κ°μ₯ λ¨Όμ μ€νλλ λ©μλλ main λ©μλμ΄λ©°, λ©μΈ μ€λ λκ° main λ©μλλ₯Ό μ€νμμΌμ€λ€. λ©μΈ μ€λ λλ main λ©μλμ μ½λλ₯Ό μ²μλΆν° λκΉμ§ μ°¨λ‘λλ‘ μ€νμν€κ³ , μ½λ λμ λ§λκ±°λ returnλ¬Έμ λ§λλ©΄ μ€νμ μ’ λ£νλ€.
λ§μ½, μ΄λ€ μλ° μ ν리μΌμ΄μ μ μμ€ μ½λκ° μ±κΈ μ€λ λλ‘ μμ±λμλ€λ©΄, κ·Έ μ ν리μΌμ΄μ μ΄ μ€νλμ΄ νλ‘μΈμ€κ° λ λ μ€λ‘μ§ λ©μΈ μ€λ λλ§ κ°μ§λ μ±κΈ μ€λ λ νλ‘μΈμ€κ° λ κ²μ΄λ€. λ°λ©΄, λ©μΈ μ€λ λμμ λ λ€λ₯Έ μ€λ λλ₯Ό μμ±νμ¬ μ€νμν¨λ€λ©΄ ν΄λΉ μ ν리μΌμ΄μ μ λ©ν° μ€λ λλ‘ λμνκ² λλ€.
λ©ν° μ€λ λ
νλμ νλ‘μΈμ€λ μ¬λ¬ κ°μ μ€λ λλ₯Ό κ°μ§ μ μμΌλ©°, μ΄λ₯Ό λ©ν° μ€λ λ νλ‘μΈμ€λΌκ³ νλ€.
μ¬λ¬ κ°μ μ€λ λλ₯Ό κ°μ§λ€λ κ²μ μ¬λ¬ μ€λ λκ° λμμ μμ μ μνν μ μμμ μλ―Ένλ©°, μ΄λ₯Ό λ©ν°μ€λ λ©μ΄λΌκ³ νλ€.
λ©ν° μ€λ λ©μ νλμ μ ν리μΌμ΄μ λ΄μ μ¬λ¬ μμ μ λμμ μννλ λ©ν° νμ€νΉμ ꡬννλ λ°μ ν΅μ¬μ μΈ μν μ μννλ€.
μλ₯Ό λ€μ΄, λ©μ μ νλ‘κ·Έλ¨μ μ¬μ©ν λ, μλλ°©μκ² λ³΄λΌ μ¬μ§μ μ λ‘λνλ©΄μ λμμ λ©μμ§λ₯Ό μ£Όκ³ λ°μ μ μλ€. μ΄μ²λΌ λ©μ μ νλ‘κ·Έλ¨μ΄ μ¬λ¬ κ°μ§ μμ μ λμμ μννλ €λ©΄, μμ μ λμμ μ€νν΄ μ€ μ€λ λκ° μΆκ°λ‘ νμνλ€.
μ€λ λμ μμ±κ³Ό μ€ν
λ©μΈ μ€λ λ μΈμ λ³λμ μμ μ€λ λλ₯Ό μ¬μ©νλ€λ κ²μ λ€μ λ§ν΄ μμ μ€λ λκ° μνν μ½λλ₯Ό μμ±νκ³ , μμ μ€λ λλ₯Ό μμ±νμ¬ μ€νμν€λ κ²μ μλ―Ένλ€.
μλ°λ κ°μ²΄μ§ν₯ μΈμ΄μ΄λ―λ‘ λͺ¨λ μλ° μ½λλ ν΄λμ€ μμ μμ±λλ―λ‘, μ€λ λκ° μνν μ½λλ ν΄λμ€ λ΄λΆμ μμ±ν΄μ£Όμ΄μΌ νλ©°, run() μ΄λΌλ λ©μλ λ΄μ μ€λ λκ° μ²λ¦¬ν μμ μ μμ±νλλ‘ λμ΄ μλ€.
run() λ©μλλ Runnable μΈν°νμ΄μ€μ Thread ν΄λμ€μ μ μλμ΄ μλ€. λ°λΌμ, μμ μ€λ λλ₯Ό μμ±νκ³ μ€ννλ λ°©λ²μ λ€μμ λ κ°μ§κ° λλ€.
- 첫 λ²μ§Έ λ°©λ²
- Runnable μΈν°νμ΄μ€λ₯Ό ꡬνν κ°μ²΄μμ run()μ ꡬννμ¬ μ€λ λλ₯Ό μμ±νκ³ , μ€ννλ λ°©λ²
- λ λ²μ§Έ λ°©λ²
- Thread ν΄λμ€λ₯Ό μμλ°μ νμ ν΄λμ€μμ run()μ ꡬννμ¬ μ€λ λλ₯Ό μμ±νκ³ μ€ννλ λ°©λ²
1. Runnable μΈν°νμ΄μ€λ₯Ό ꡬνν κ°μ²΄μμ run()μ ꡬννμ¬ μ€λ λλ₯Ό μμ±νκ³ μ€ννλ λ°©λ²
public class ThreadExample01 {
public static void main(String[] args) {
Thread thread1 = new Thread(new ThreadTask1());
thread1.start();
for (int i = 0; i < 100; i++) {
System.out.print("@");
}
}
}
class ThreadTask1 implements Runnable{
public void run(){
for(int i=0;i<100;i++){
System.out.print("#");
}
}
}
> Task :ThreadExample01.main()
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@###@###@@@@@@@@@@@@@@@@@@@@@@@@@@@@@###@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@###########################################################################################
@μ #μ΄ μμ¬ μμ΄ λ©μΈ μ€λ λμ μμ μ€λ λκ° λμμ λ³λ ¬λ‘ μ€ν(λμμ λ 립μ μΌλ‘ μ€νλλ€)λλ©΄μ, κ°κ° main λ©μλμ run() λ©μλμ μ½λλ₯Ό μ€νμμΌ°μμ μ μ μλ€.
2. Thread ν΄λμ€λ₯Ό μμλ°μ νμ ν΄λμ€μμ run()μ ꡬννμ¬ μ€λ λλ₯Ό μμ±νκ³ μ€ννλ λ°©λ²
package org.example.dev;
public class ThreadExample02 {
public static void main(String[] args) {
ThreadTask2 thread2 = new ThreadTask2();
thread2.start();
for (int i = 0; i < 100; i++) {
System.out.print("@");
}
}
}
class ThreadTask2 extends Thread{
public void run() {
for (int i = 0; i < 100; i++) {
System.out.print("#");
}
}
}
> Task :ThreadExample02.main()
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@################@@@@@@@@@###########@@@@@@##@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#######################################################################
λ λ²μ§Έ λ°©λ² μμ μμ μ μ¬ν κ²°κ³Όλ₯Ό μ»μ μ μλ€.
μ λκ°μ§ λ°©λ² λͺ¨λ μμ μ€λ λλ₯Ό λ§λ€κ³ , run() λ©μλμ μμ±λ μ½λλ₯Ό μ²λ¦¬νλ λμΌν λ΄λΆ λμμ μννλ€.
μ΅λͺ κ°μ²΄λ₯Ό μ¬μ©νμ¬ μ€λ λ μμ±νκ³ μ€ννκΈ°
1. Runnable μ΅λͺ ꡬν κ°μ²΄λ₯Ό νμ©ν μ€λ λ μμ± λ° μ€ν
package org.example.dev;
public class ThreadExample03 {
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.print("#");
}
}
});
thread1.start();
for (int i = 0; i < 100; i++) {
System.out.print("@");
}
}
}
2. Thread μ΅λͺ νμ κ°μ²΄λ₯Ό νμ©ν μ€λ λ μμ± λ° μ€ν
package org.example.dev;
public class ThreadExample04 {
public static void main(String[] args) {
Thread thread2 = new Thread() {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.print("#");
}
}
};
thread2.start();
for (int i = 0; i < 100; i++) {
System.out.print("@");
}
}
}
μ€λ λ λκΈ°ν λ¬Έμ
μ±κΈ μ€λ λ νλ‘μΈμ€μ κ²½μ°, λ°μ΄ν°μ λ¨ νλμ μ€λ λλ§ μ κ·ΌνκΈ° λλ¬Έμ λ¬Έμ λ κ²μ΄ μμΌλ, λ©ν° μ€λ λ νλ‘μΈμ€μ κ²½μ°, λ μ€λ λκ° κ°μ λ°μ΄ν°λ₯Ό 곡μ νκ² λμ΄ λ¬Έμ κ° λ°μν μ μλ€.
package org.example.thread;
public class ThreadExample05 {
public static void main(String[] args) {
Runnable threadTask3 = new ThreadTask3();
Thread thread3_1 = new Thread(threadTask3);
Thread thread3_2 = new Thread(threadTask3);
thread3_1.setName("κΉμ½λ©");
thread3_2.setName("λ°μλ°");
thread3_1.start();
thread3_2.start();
}
}
class Account{
private int balance=1000;
public int getBalance(){
return balance;
}
public boolean withdraw(int money){
if(balance>=money){
try{
Thread.sleep(1000);
}catch (Exception error) {}
balance -= money;
return true;
}
return false;
}
}
class ThreadTask3 implements Runnable{
Account account = new Account();
public void run(){
while(account.getBalance()>0){
int money = (int)(Math.random() * 3 + 1) * 100;
boolean denied = !account.withdraw(money);
System.out.println(String.format("Withdraw %dβ© By %s. Balance : %d %s",
money, Thread.currentThread().getName(), account.getBalance(), denied ? "-> DENIED" : "")
);
}
}
}
> Task :ThreadExample05.main()
Withdraw 100β© By λ°μλ°. Balance : 900
Withdraw 300β© By κΉμ½λ©. Balance : 900
Withdraw 300β© By λ°μλ°. Balance : 600
Withdraw 100β© By κΉμ½λ©. Balance : 600
Withdraw 300β© By κΉμ½λ©. Balance : 300
Withdraw 100β© By λ°μλ°. Balance : 200
Withdraw 300β© By κΉμ½λ©. Balance : -100
Withdraw 200β© By λ°μλ°. Balance : -300
μΆλ ₯ κ²°κ³Όλ₯Ό 보면, μΈμΆκΈκ³Ό μμ‘μ΄ μ λλ‘ μΆλ ₯λμ§ μκ³ μμμ μ μ μλ€.
μ΄λ λ μ€λ λ κ°μ κ°μ²΄κ° 곡μ λκΈ° λλ¬Έμ λ°μνλ μ€λ₯λ‘, κ°μ΄ μ μ΄λ κ² μΆλ ₯λμλμ§ μΆμΈ‘νκΈ°κ° μ΄λ ΅λ€.
λν, withdraw()μμ μμ‘μ΄ μΈμΆλκ³ μ νλ κΈμ‘λ³΄λ€ λ§μ κ²½μ°μλ§ μΈμΆμ΄ κ°λ₯νλλ‘ μ½λλ₯Ό μμ±ν΄ λμμμλ λΆκ΅¬νκ³ (if(balance>= money) ~), λ§μΉ μ‘°κ±΄λ¬Έμ΄ λ¬΄μλ κ²μ²λΌ μμμ μμ‘μ΄ λ°μνλ κ²μ νμΈν μ μλ€.
μ¬κΈ°μμ μμμ μμ‘μ΄ λ°μνλ μ΄μ λ, λ μ€λ λκ° νλμ Accountκ°μ²΄λ₯Ό 곡μ νλ μν©μμ, ν μ€λ λκ° if λ¬Έμ 쑰건μμ trueλ‘ νκ°νμ¬ if λ¬Έμ μ€νλΆλ‘ μ½λμ νλ¦μ΄ μ΄λνλ μμ μ λ€λ₯Έ μ€λ λκ° λΌμ΄λ€μ΄ balanceλ₯Ό μΈμΆνκΈ° λλ¬Έμ΄λ€.
κ·Έλ¦¬κ³ , μ μ μλ μμΈμ μν΄ μΈμΆμ μ€ν¨ν κ²½μ°μ --> DENIEDκ° μ λλ‘ μΆλ ₯λμ§ μλ λ¬Έμ λ λ°μνλ€.
μ΄λ¬ν μν©μ΄ λ°μνμ§ μκ² νλ κ²μ μ€λ λ λκΈ°νλΌκ³ νλ€.
μ€λ λ λκΈ°ν
πλ€μμ μ€λ λκ° ν 리μμ€μ μ κ·Όνλ € ν λ, μ¬μ©νλ €λ μ€λ λλ₯Ό μ μΈν λλ¨Έμ§ μ€λ λλ€μ 리μμ€λ₯Ό μ¬μ©νμ§ λͺ»νλλ‘ λ§λ κ².
μκ³ μμ(Critical section)κ³Ό λ½(Lock)
μκ³ μμμ μ€λ‘μ§ νλμ μ€λ λλ§ μ½λλ₯Ό μ€νν μ μλ μ½λ μμμ μλ―Ένλ©°, λ½μ μκ³ μμμ ν¬ν¨νκ³ μλ κ°μ²΄μ μ κ·Όν μ μλ κΆνμ μλ―Ένλ€.
μ¦, μκ³ μμμΌλ‘ μ€μ λ κ°μ²΄κ° λ€λ₯Έ μ€λ λμ μν΄ μμ μ΄ μ΄λ£¨μ΄μ§κ³ μμ§ μμ λ, μμμ μ€λ λ Aλ ν΄λΉ κ°μ²΄μ λν λ½μ νλνμ¬ μκ³ μμ λ΄μ μ½λλ₯Ό μ€νν μ μλ€.
μ΄λ, μ€λ λ Aκ° μκ³ μμ λ΄μ μ½λλ₯Ό μ€ν μ€μΌ λμλ λ€λ₯Έ μ€λ λλ€μ λ½μ΄ μμΌλ―λ‘ μ΄ κ°μ²΄μ μκ³ μμ λ΄μ μ½λλ₯Ό μ€νν μ μλ€.
μ μ λ€, μ€λ λ Aκ° μκ³ μμ λ΄μ μ½λλ₯Ό λͺ¨λ μ€ννλ©΄ λ½μ λ°λ©νκ³ , μ΄λ λΆν° λ€λ₯Έ μ€λ λ μ€ νλκ° λ½μ νλνμ¬ μκ³ μμ λ΄μ μ½λλ₯Ό μ€νν μ μλ€.
μ μμ μμ μ°λ¦¬μκ² νμνλ κ²μ λ μ€λ λκ° λμμ μ€ννλ©΄ μλλ μμμ μ€μ νλ κ²μ΄λ€. μ¦, withdraw() λ©μλλ₯Ό λ μ€λ λκ° λμμ μ κ·Όνμ§ λͺ»νλλ‘ ν΄μΌ νλ€.
π‘withdraw() λ©μλλ₯Ό μκ³ μμμΌλ‘ μ€μ νλ€.
νΉμ μ½λ ꡬκ°μ μκ³ μμμΌλ‘ μ€μ ν λλ synchronized λΌλ ν€μλλ₯Ό μ¬μ©νλ€.
1. λ©μλ μ 체λ₯Ό μκ³ μμμΌλ‘ μ§μ νκΈ°
public synchronized boolean withdraw(int money){
if(balance>=money){
try{
Thread.sleep(1000);
}catch (Exception error) {}
balance -= money;
return true;
}
return false;
}
μ΄λ κ² λ©μλ μ 체λ₯Ό μκ³ μμμΌλ‘ μ§μ νλ©΄ λ©μλκ° νΈμΆλμμ λ, λ©μλλ₯Ό μ€νν μ€λ λλ λ©μλκ° ν¬ν¨λ κ°μ²΄μ λ½μ μ»λλ€.
μ¦, withdraw()κ° νΈμΆλλ©΄, withdraw()λ₯Ό μ€ννλ μ€λ λλ withdraw()κ° ν¬ν¨λ κ°μ²΄μ λ½μ μ»μΌλ©°, ν΄λΉ μ€λ λκ° λ½μ λ°λ©νκΈ° μ΄μ μ λ€λ₯Έ μ€λ λλ ν΄λΉ λ©μλμ μ½λλ₯Ό μ€ννμ§ λͺ»νκ² λλ€.
2. νΉμ ν μμμ μκ³ μμμΌλ‘ μ§μ νκΈ°
public synchronized boolean withdraw(int money){
synchronized (this){
if(balance>=money){
try{
Thread.sleep(1000);
}catch (Exception error) {}
balance -= money;
return true;
}
return false;
}
}
νΉμ μμμ μκ³ μμμΌλ‘ μ§μ νλ €λ©΄ μμ κ°μ΄ synchronized ν€μλμ ν¨κ» μκ΄νΈ μμ ν΄λΉ μμμ΄ ν¬ν¨λ κ°μ²΄μ μ°Έμ‘°λ₯Ό λ£κ³ , μ€κ΄νΈ({})λ‘ λΈλ‘μ μ΄μ΄, λΈλ‘ λ΄μ μ½λλ₯Ό μμ±νλ©΄ λλ€.
μ΄ κ²½μ°μλ λ§μ°¬κ°μ§λ‘, μκ³ μμμΌλ‘ μ€μ ν λΈλ‘μ μ½λλ‘ μ½λ μ€ν νλ¦μ΄ μ§μ ν λ, ν΄λΉ μ½λλ₯Ό μ€ννκ³ μλ μ€λ λκ° thisμ ν΄λΉνλ κ°μ²΄μ λ½μ μ»κ³ , λ°°νμ μΌλ‘ μκ³ μμ λ΄μ μ½λλ₯Ό μ€ννλ€.
1λ² μ²λΌ λ©μλ μ 체μ λ½μ κ±°λ κ²λ³΄λ€ synchronized λΈλ‘μΌλ‘ μκ³ μμμ μ΅μνν΄ ν¨μ¨μ μΈ νλ‘κ·Έλ¨μ΄ λλλ‘ νλ κ²μ΄ λ°λμ§νλ€.
Thread Safe
'μ¬λ¬ μ€λ λκ° λμμ μ΄λ€ 리μμ€λ₯Ό μ κ·Όν΄λ νλ‘κ·Έλ¨μ΄ μμ μ μΌλ‘ λμνλ κ²'μ λ§νλ€.
μ¦, Thread Safeλ₯Ό 보μ₯νκΈ° μν λ°©λ² μ€ νλκ° μ€λ λ λκΈ°νμ΄λ©°, Thread Safeλ Immutable Objectλ₯Ό μμ±ν΄μλ 보μ₯μ΄ κ°λ₯νλ€.
Immutable Objectλ₯Ό μ¬μ©νλ λ°©λ²μ λ€μκ³Ό κ°λ€.
'Javaπ' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
Spring MVC - JPA κΈ°λ° λ°μ΄ν° μ‘μΈμ€ κ³μΈ΅(1) (0) | 2023.05.06 |
---|---|
πJVMμ GC(Garbage Collector) (0) | 2023.03.13 |
πμμ±μ, thisμ this(), κ·Έλ¦¬κ³ λ΄λΆν΄λμ€ (1) | 2023.02.24 |
πOOPμ ν΄λμ€, νλ, λ©μλ, staticκΉμ§ (0) | 2023.02.23 |
λκΈ°μ & λΉλκΈ°μ (0) | 2023.02.16 |