์ค๋ ํ ๊ณต๋ถ๐ง
์ค์
- ์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ (SQL, Java) 1๋ฌธ์ ํ์ด & ๋ธ๋ก๊ทธ ์ ๋ฆฌ
- Java ๋ฌธ๋ฒ ์ข ํฉ๋ฐ 5์ฃผ์ฐจ ๊ฐ์ ๋ณต์ต
์คํ
- Java ๋ฌธ๋ฒ ์ข ํฉ๋ฐ 5์ฃผ์ฐจ ๊ฐ์ ๋ณต์ต
- TIL ๋ธ๋ก๊ทธ ์์ฑ
์ค๋ ์ป์ ๋ด์ฉ ์ ๋ฆฌโ๏ธ
Java ๋ฌธ๋ฒ ์ข ํฉ๋ฐ_5์ฃผ์ฐจ ๊ฐ์ ๋ด์ฉ ์ ๋ฆฌ
Process์ Thread
Process : ์ด์์ฒด์ ๋ก๋ถํฐ ์์์ ํ ๋น๋ฐ๋ ์์ ์ ๋จ์
- ์คํ ์ค์ธ ํ๋ก๊ทธ๋จ์ ์๋ฏธํ๋ค.
- OS๊ฐ ํ๋ก๊ทธ๋จ ์คํ์ ์ํ ํ๋ก์ธ์ค๋ฅผ ํ ๋นํด์ค ๋ ํ๋ก์ธ์ค ์์ ํ๋ก๊ทธ๋จ Code์ Data ๊ทธ๋ฆฌ๊ณ ๋ฉ๋ชจ๋ฆฌ ์์ญ(Stack, Heap)์ ํจ๊ป ํ ๋นํด์ค๋ค.
- Code๋ Java main ๋ฉ์๋์ ๊ฐ์ ์ฝ๋๋ฅผ ๋งํ๋ค.
- Data๋ ํ๋ก๊ทธ๋จ์ด ์คํ ์ค ์ ์ฅํ ์ ์๋ ์ ์ฅ๊ณต๊ฐ์ ์๋ฏธํ๋ค.
- ์ ์ญ๋ณ์, ์ ์ ๋ณ์(static), ๋ฐฐ์ด ๋ฑ ์ด๊ธฐํ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๊ณต๊ฐ
- Memory(๋ฉ๋ชจ๋ฆฌ ์์ญ) → ๋์ ์ผ๋ก ํ์ํ ๋ณ์ ์ ์ฅํ๋ ๊ณต๊ฐ
- Stack : ์ง์ญ๋ณ์, ๋งค๊ฐ๋ณ์ ๋ฆฌํด ๋ณ์ ์ ์ฅํ๋ ๊ณต๊ฐ
- Heap : ํ๋ก๊ทธ๋จ์ด ๋์ ์ผ๋ก ํ์ํ ๋ณ์๋ฅผ ์ ์ฅํ๋ ๊ณต๊ฐ (new( ), mallock( ))
- ๊ฐ ํ๋ก๊ทธ๋จ์ Process๋ฅผ ํตํด Code, Data, Memory(Stack, Heap)๋ฅผ OS๋ก๋ถํฐ ํ ๋น๋ฐ๋๋ค.
Thread : ํ๋ก์ธ์ค๊ฐ ํ ๋น๋ฐ์ ์์์ ์ด์ฉํ๋(๊ณต์ ํ๋) ์คํ์ ๋จ์ → ์์ ์, ์ผ๊พผ
- Process๊ฐ ์์ ์ค์ธ ํ๋ก๊ทธ๋จ์์ ์คํ์์ฒญ์ด ๋ค์ด์ค๋ฉด Thread(์ผ๊พผ)์ ๋ง๋ค์ด ์ฒ๋ฆฌํ๋๋ก ํ๋ค.
- Thread๋ค์ ์คํ์ ์ํ ํ๋ก์ธ์ค ๋ด ์ฃผ์๊ณต๊ฐ์ด๋ ๋ฉ๋ชจ๋ฆฌ๊ณต๊ฐ(Heap)์ ๊ณต์ ๋ฐ๋๋ค.
- Thread(์ผ๊พผ)๋ค์ ๊ฐ๊ฐ ๋ช ๋ น์ฒ๋ฆฌ๋ฅผ ์ํ ์์ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๊ณต๊ฐ(Stack)์ ํ ๋น๋ฐ๋๋ค.
- Java Thread
- Java Main Thread๋ถํฐ ์คํ๋๋ฉฐ JVM์ ์ํด ์คํ๋๋ค.
- Java Main Thread : Java ํ๋ก๊ทธ๋จ์ด ์คํ๋ ๋ ๋ฌด์กฐ๊ฑด ์ฒ์์ ๊ฐ์ด ์คํ๋๋ Thread์ด๋ค.
Multi Thread
Java๋ Main Thread๊ฐ main( ) ๋ฉ์๋๋ฅผ ์คํ์ํค๋ฉด์ ์์์ด ๋๋ค.
- Main Thread๋ ํ์์ ๋ฐ๋ผ์ ์์ Thread๋ค์ ์์ฑํด์ ๋ณ๋ ฌ๋ก ์ฝ๋๋ฅผ ์คํ์ํฌ ์ ์๋ค.
- Java๋ ๋ฉํฐ Thread๋ฅผ ์ง์ํ๋ค.
- Java ํ๋ก๊ทธ๋จ์ Main Thread์ธ์ ๋ค๋ฅธ ์์
Thread๋ค์ ์์ฑํ์ฌ ์ฌ๋ฌ ๊ฐ์ ์คํํ๋ฆ์ ๋ง๋ค ์ ์๋ค.
- Main Thread ์์์ ๋ง๋ค์ด์ ์คํ์ํค๋ ๊ฒ์ด๋ค.
- ์ฅ์
- ์ฌ๋ฌ ๊ฐ์ Thread(์คํ ํ๋ฆ)์ ํตํด ์ฌ๋ฌ ๊ฐ์ ์์ ์ ๋์์ ํ ์ ์์ด์ ์ฑ๋ฅ์ด ์ข์์ง๋ค.
- Stack์ ์ ์ธํ ๋ชจ๋ ์์ญ์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ๊ธฐ ๋๋ฌธ์ ์์์ ๋ณด๋ค ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
- ์๋ต Thread์ ์์ Thread๋ฅผ ๋ถ๋ฆฌํ์ฌ ๋น ๋ฅด๊ฒ ์๋ต์ ์ค ์ ์๋ค. (๋น๋๊ธฐ)
- ๋จ์
- Process์ ์์์ ๊ณต์ ํ๋ฉด์ ์์ ์ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์์์ ์๋ก ์ฌ์ฉํ๋ ค๊ณ ํ๋ ์ถฉ๋์ด ๋ฐ์ํ๋ ๊ฒฝ์ฐ๋ฅผ ์๋ฏธํ๋ค.
- ๊ต์ฐฉ์ํ(Dead-Lock)์ด ๋ฐ์ํ ์ ์๋ค.
Thread์ Runnable
Thread
package week05.thread;
// 1. Thread Class๋ฅผ ์ด์ฉํ๋ ๊ฒ (์์)
//
public class TestThread extends Thread{
@Override
public void run () {
// ์ค์ ์ฐ๋ฆฌ๊ฐ ์ฐ๋ ๋์์ ์ํํ ์์
for (int i = 0; i < 100; i++) {
System.out.print("*");
}
}
}
- ํต์ฌ์ run( ) ๋ฉ์๋์ด๋ค.
- run( ) ๋ฉ์๋์ ์์ฑ๋ ์ฝ๋๊ฐ Thread๊ฐ ์ํํ ์์ ์ด๋ค.
Runnable
package week05.thread;
public class TestRunnable implements Runnable{
@Override
public void run() {
// Thread์์ ์ํํ ์์
์ ์!!
for (int i = 0; i < 100; i++) {
System.out.print("$");
}
}
}
- ์ฌ๊ธฐ์์ run( ) ๋ฉ์๋๋ ๋ง์ฐฌ๊ฐ์ง๋ก Thread๊ฐ ์ํํ ์์ ์ด๋ค.
- Java๋ ๋ค์ค ์์์ ์ง์ํ์ง ์๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ Thread๋ฅผ ์์ ๋ฐ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ํ์ฅ์ฑ์ด ๋งค์ฐ ๋จ์ด์ง๋ค.
- ํ์ง๋ง Runnable์ ์ธํฐํ์ด์ค์ด๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ํ์ํ ํด๋์ค๋ฅผ ์์๋ฐ์ ์ ์๋ค. ๋ฐ๋ผ์ ํ์ฅ์ฑ์ ๋งค์ฐ ์ ๋ฆฌํ๋ค.
๋๋ค์
package week05.thread;
public class Main {
public static void main(String[] args) {
// ์ต๋ช
ํจ์์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ค.
Runnable task = () -> {
int sum = 0;
for (int i = 0; i < 50; i++) {
sum += i;
System.out.println(sum);
}
System.out.println(Thread.currentThread().getName() + " ์ต์ข
ํฉ : " + sum);
};
Thread thread1 = new Thread(task);
thread1.setName("thread1");
Thread thread2 = new Thread(task);
thread2.setName("thread2");
thread1.start();
thread2.start();
}
}
- run( ) ๋ฉ์๋์ ์์ฑํ๋ Thread๊ฐ ์ํํ ์์ ์ ์คํ ๋ธ๋ก { } ์์ ์์ฑํ๋ฉด ๋๋ค.
- setname( ) ๋ฉ์๋๋ ์ฐ๋ ๋์ ์ด๋ฆ์ ๋ถ์ฌํ ์ ์๋ค.
- Thread.currentThread( ).getName( )์ ํ์ฌ ์คํ ์ค์ธ Thread์ ์ด๋ฆ์ ๋ฐํํ๋ค.
๋ฐ๋ชฌ Thread์ ์ฌ์ฉ์ Thread
๋ฐ๋ชฌ Thread
- ๋ณด์ด์ง ์๋ ๊ณณ(background)์์ ์คํ๋๋ ๋ฎ์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง Thread๋ฅผ ๋งํ๋ค.
- ๋ณด์กฐ์ ์ธ ์ญํ ์ ๋ด๋นํ๋ฉฐ ๋ํ์ ์ธ ๋ฐ๋ชฌ Thread๋ก๋ ๊ฐ๋น์ง ์ปฌ๋ ํฐ(GC)๊ฐ ์๋ค.
package week05.thread.demon;
public class Main {
public static void main(String[] args) {
Runnable demon = () -> {
for (int i = 0; i < 1000000; i++) {
System.out.println(i + "๋ฒ์งธ demon");
}
};
// ์ฐ์ ์์๊ฐ ๋ฎ๋ค! -> ์๋์ ์ผ๋ก ๋ค๋ฅธ Thread์ ๋นํด ๋ฆฌ์์ค๋ฅผ ์ ๊ฒ ํ ๋น๋ฐ๋๋ค.
Thread thread = new Thread(demon);
thread.setDaemon(true);
thread.start();
for (int i = 0; i < 100; i++) {
System.out.println(i + "๋ฒ์งธ task");
}
}
}
- ์ฐ์ ์์๊ฐ ๋ฎ๊ณ ๋ค๋ฅธ Thread๊ฐ ๋ชจ๋ ์ข ๋ฃ๋๋ฉด ๊ฐ์ ์ข ๋ฃ๋นํ๋ค.
์ฌ์ฉ์ Thread
- ๋ณด์ด๋ ๊ณณ(foreground)์์ ์คํ๋๋ ๋์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง Thread๋ฅผ ๋งํ๋ค.
- ํ๋ก๊ทธ๋จ ๊ธฐ๋ฅ์ ๋ด๋นํ๋ฉฐ ๋ํ์ ์ธ ์ฌ์ฉ์ Thread๋ก๋ Main Thread๊ฐ ์๋ค.
- ์ฌ์ฉ์ Thread ๋ง๋๋ ๋ฒ : ๊ธฐ์กด์ ๋ง๋ค์๋ Thread๋ค์ด ์ ๋ถ ์ฌ์ฉ์ Thread์ด๋ค.
JVM์ ์ฌ์ฉ์ Thread์ ์์ ์ด ๋๋๋ฉด ๋ฐ๋ชฌ Thread๋ ์๋์ผ๋ก ์ข ๋ฃ์์ผ ๋ฒ๋ฆฐ๋ค.
Thread ์ฐ์ ์์์ Thread ๊ทธ๋ฃน
Thread ์ฐ์ ์์
- Thread ์์
์ ์ค์๋์ ๋ฐ๋ผ์ Thread์ ์ฐ์ ์์๋ฅผ ๋ถ์ฌํ ์ ์๋ค.
- ํ Process์ ์ฌ๋ฌ ๊ฐ์ Thread๊ฐ ์์ ์ ์๋ค. ๋ชจ๋ Thread๊ฐ ๋ค ๋๊ฐ์ด ์ค์ํ Thread๋ ์๋ ๊ฒ์ด๋ค.
- ์์ ์ ์ค์๋๊ฐ ๋์ ๋ ์ฐ์ ์์๋ฅผ ๋๊ฒ ์ง์ ํ๋ฉด ๋ ๋ง์ ์์ ์๊ฐ์ ๋ถ์ฌ๋ฐ์ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌ๋ ์ ์๋ค.
- Thread๋ ์์ฑ๋ ๋ ์ฐ์ ์์๊ฐ ์ ํด์ง๋ค.
- ์ต๋ ์ฐ์ ์์ (MAX_PRIORITY) = 10
- ์ต์ ์ฐ์ ์์ (MIN_PRIORITY) = 1
- ๋ณดํต ์ฐ์ ์์ (NROM_PRIORITY) = 5
- ๊ธฐ๋ณธ ๊ฐ์ด ๋ณดํต ์ฐ์ ์์์ด๋ค.
- ์ฐ์ ์์์ ๋ฒ์๋ OS๊ฐ ์๋๋ผ JVM์์ ์ค์ ํ ์ฐ์ ์์์ด๋ค.
- Thread ์ฐ์ ์์๋ setPriority( ) ๋ฉ์๋๋ก ํ์ธํ ์ ์๋ค.
- getPriority( ) ๋ฉ์๋๋ก ์ฐ์ ์์๋ฅผ ๋ฐํํ์ฌ ํ์ธํ ์ ์๋ค.
package week05.thread.priority;
public class Main {
public static void main(String[] args) {
Runnable task1 = () -> {
for (int i = 0; i < 100; i++) {
System.out.print("$");
}
};
Runnable task2 = () -> {
for (int i = 0; i < 100; i++) {
System.out.print("*");
}
};
Thread thread1 = new Thread(task1);
thread1.setPriority(8);
int threadPriority = thread1.getPriority();
System.out.println("threadPriority = " + threadPriority);
Thread thread2 = new Thread(task2);
thread2.setPriority(2);
thread1.start();
thread2.start();
}
}
- Thread1์ด ๋ฆฌ์์ค๋ฅผ ๋ ๋ง์ด ๊ฐ์ ธ๊ฐ๋ค. ๋ ๋นจ๋ฆฌ ๋๋ ๊ฐ๋ฅ์ฑ์ด ๋๋ค.
- ๋ฌด๊ฑฐ์ด ์์ ์ ๋๋ฆด ๋ ๋น์ ๋ณผ ์ ์๋ค.
Thread ๊ทธ๋ฃน
์๋ก ๊ด๋ จ์ด ์๋ thread๋ค์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ด์ ๋ค๋ฃฐ ์ ์๋ค.
- Thread๋ค์ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ทธ๋ฃน์ ํฌํจ๋์ด ์๋ค.
- JVM์ด ์์๋๋ฉด system ๊ทธ๋ฃน์ด ์์ฑ๋๊ณ Thread๋ค์ ๊ธฐ๋ณธ์ ์ผ๋ก system ๊ทธ๋ฃน์ ํฌํจ๋๋ค.
- Main Thread๋ system ๊ทธ๋ฃน ํ์์ ์๋ main ๊ทธ๋ฃน์ ํฌํจ๋๋ค.
- ๋ชจ๋ Thread๋ค์ ๋ฐ๋์ ํ๋์ ๊ทธ๋ฃน์ ํฌํจ๋์ด ์์ด์ผ ํ๋ค. → ์๋์ผ๋ก main ๊ทธ๋ฃน์ ํฌํจ๋๋ค.
package week05.thread.group;
public class Main {
public static void main(String[] args) {
Runnable task = () -> {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
break;
}
}
System.out.println(Thread.currentThread().getName() + " Interrupted");
};
// ThreadGroup ํด๋์ค๋ก ๊ฐ์ฒด๋ฅผ ๋ง๋ญ๋๋ค.
ThreadGroup group1 = new ThreadGroup("Group1");
// Thread ๊ฐ์ฒด ์์ฑ์ ์ฒซ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ก ๋ฃ์ด์ค๋๋ค.
// Thread(ThreadGroup group, Runnable target, String name)
Thread thread1 = new Thread(group1, task, "Thread 1");
Thread thread2 = new Thread(group1, task, "Thread 2");
// Thread์ ThreadGroup ์ด ํ ๋น๋๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
System.out.println("Group of thread1 : " + thread1.getThreadGroup().getName());
System.out.println("Group of thread2 : " + thread2.getThreadGroup().getName());
thread1.start();
thread2.start();
try {
// ํ์ฌ ์ฐ๋ ๋๋ฅผ ์ง์ ๋ ์๊ฐ๋์ ๋ฉ์ถ๊ฒ ํฉ๋๋ค.
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// interrupt()๋ ์ผ์์ ์ง ์ํ์ธ ์ฐ๋ ๋๋ฅผ ์คํ๋๊ธฐ ์ํ๋ก ๋ง๋ญ๋๋ค.
group1.interrupt();
}
}
Thread ์ํ์ ์ ์ด
Thread ์ํ
Thread๋ฅผ ์ ๋ฆฌํ ํ
์ํ | Enum(์์) | ์ค๋ช |
๊ฐ์ฒด ์์ฑ | NEW | Thread ๊ฐ์ฒด ์์ฑ, ์์ง start( ) ๋ฉ์๋ ํธ์ถ ์ ์ ์ํ |
์คํ ๋๊ธฐ | RUNNABLE | ์คํ ์ํ๋ก ์ธ์ ๋ ์ง ๊ฐ ์ ์๋ ์ํ |
์ผ์์ ์ง | WAITING | ๋ค๋ฅธ ์ฐ๋ ๋๊ฐ ํต์ง(notify)ํ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ์ํ |
์ผ์์ ์ง | TIMED_WAITING | ์ฃผ์ด์ง ์๊ฐ ๋์ ๊ธฐ๋ค๋ฆฌ๋ ์ํ |
์ผ์์ ์ง | BLOCKED | ์ฌ์ฉํ๊ณ ์ ํ๋ ๊ฐ์ฒด์ Lock์ด ํ๋ฆด ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ์ํ |
์ข ๋ฃ | TERMINATED | Thread์ ์์ ์ด ์ข ๋ฃ๋ ์ํ |
Thread ์ ์ด
sleep( ), interrupt( )
sleep( )
- ํ์ฌ Thread๋ฅผ ์ง์ ๋ ์๊ฐ๋์ ๋ฉ์ถ๊ฒ ํ๋ค.
- Thread ์๊ธฐ์์ ์ ๋ํด์๋ง ๋ฉ์ถ๊ฒ ํ ์ ์๋ค.
package week05.thread.stat.sleep;
public class Main {
public static void main(String[] args) {
Runnable task = () -> {
try {
// (1) ์์ธ์ฒ๋ฆฌ ํ์!
// - interrupt() ๋ฅผ ๋ง๋๋ฉด ๋ค์ ์คํ๋๊ธฐ ๋๋ฌธ์
// - InterruptedException์ด ๋ฐ์ํ ์ ์๋ค.
// (2) ํน์ Thread ์ง๋ชฉ ๋ถ๊ฐ
Thread.sleep(2000); // TIMED_WAITING (์ฃผ์ด์ง ์๊ฐ๋์๋ง ๊ธฐ๋ค๋ฆฌ๋ ์ํ)
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task : " + Thread.currentThread().getName());
};
Thread thread = new Thread(task, "Thread"); // NEW
thread.start(); // NEW -> RUNNABLE
try {
// 1์ด๊ฐ ์ง๋๊ณ ๋๋ฉด runnable ์ํ๋ก ๋ณํ์ฌ ๋ค์ ์คํ๋๋ค!
// ํน์ ์ค๋ ๋๋ฅผ ์ง๋ชฉํด์ ๋ฉ์ถ๊ฒ ํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํ๋ค!
// Static member 'java.lang.Thread.sleep(long)' accessed via instance reference
thread.sleep(1000);
System.out.println("sleep(1000) : " + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
interrupt( )
- ์ผ์์ ์ง ์ํ์ธ Thread๋ฅผ ์คํ๋๊ธฐ ์ํ๋ก ๋ง๋ ๋ค.
package week05.thread.stat.interrupt;
public class Main {
public static void main(String[] args) {
Runnable task = () -> {
// interrupted ์ํ๋ฅผ ์ฒดํฌํด์ ์ฒ๋ฆฌํ๋ฉด ์ค๋ฅ๋ฅผ ๋ฐฉ์ง
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
break;
}
}
System.out.println("task : " + Thread.currentThread().getName());
};
Thread thread = new Thread(task, "Thread");
thread.start();
thread.interrupt();
System.out.println("thread.isInterrupted() = " + thread.isInterrupted());
}
}
join( )
- ์ ํด์ง ์๊ฐ ๋์ ์ง์ ํ Thread๊ฐ ์์ ํ๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฐ๋ค.
- ์๊ฐ์ ์ง์ ํ์ง ์์์ ๋๋ ์ง์ ํ Thread์ ์์ ์ด ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค.
package week05.thread.stat.join;
// ์ ํด์ง ์๊ฐ ๋์ ์ง์ ํ ์ฐ๋ ๋๊ฐ ์์
ํ๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฐ๋ค.
// - ์๊ฐ์ ์ง์ ํ์ง ์์์ ๋๋ ์ง์ ํ Thread์ ์์
์ด ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค.
public class Main {
public static void main(String[] args) {
Runnable task = () -> {
try {
Thread.sleep(5000); // 5์ด
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(task, "thread"); // NEW
thread.start(); // NEW -> Runnable
long start = System.currentTimeMillis(); // ๋ช ์ด์ ๋ ์์๋๋์ง ๊ณ์ฐํด๋ณด๊ธฐ ์ํด ๋ฐ์์จ๋ค.
try {
// ์๊ฐ์ ์ง์ ํ์ง ์์๊ธฐ ๋๋ฌธ์ thread๊ฐ ์์
์ ๋๋ผ ๋๊น์ง main thread๋ ๊ธฐ๋ค๋ฆฌ๊ฒ ๋๋ค.
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// thread ์ ์์์๊ฐ์ธ 5000ms ๋์ main ์ฐ๋ ๋๊ฐ ๊ธฐ๋ค๋ ธ๊ธฐ ๋๋ฌธ์ 5000์ด์์ด ์ถ๋ ฅ๋ฉ๋๋ค.
System.out.println("์์์๊ฐ = " + (System.currentTimeMillis() - start));
}
}
yield( )
- ๋จ์ ์๊ฐ์ ๋ค์ Thread์๊ฒ ์๋ณดํ๊ณ Thread ์์ ์ ์คํ๋๊ธฐ ์ํ๊ฐ ๋๋ค.
package week05.thread.stat.yield;
// ๋จ์ ์๊ฐ์ ๋ค์ Thread์๊ฒ ์๋ณดํ๊ณ Thread ์์ ์ ์คํ๋๊ธฐ ์ํ๊ฐ ๋๋ค.
// thread1๊ณผ thread2๊ฐ ๊ฐ์ด 1์ด์ ํ ๋ฒ์ฉ ์ถ๋ ฅ๋๋ค๊ฐ
// 5์ด ๋ค์ thread1์์ InterruptedException์ด
// ๋ฐ์ํ๋ฉด์ Thread.yield(); ์ด ์คํ๋์ด thread1์
// ์คํ๋๊ธฐ ์ํ๋ก ๋ณ๊ฒฝ๋๋ฉด์ ๋จ์ ์๊ฐ์ thread2์๊ฒ ์๋ณด๋๋ค.
public class Main {
public static void main(String[] args) {
Runnable task = () -> {
try {
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
}
} catch (InterruptedException e) {
Thread.yield();
}
};
Thread thread1 = new Thread(task, "thread1"); // NEW
Thread thread2 = new Thread(task, "thread2"); // NEW
thread1.start(); // NEW -> Runnable
thread2.start(); // NEW -> Runnable
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread1.interrupt();
}
}
synchronized( )
- Multi Thread์ ๊ฒฝ์ฐ ์ฌ๋ฌ Thread๊ฐ ํ ํ๋ก์ธ์ค์ ์์์ ๊ณต์ ํด์ ์์
ํ๊ธฐ ๋๋ฌธ์ ์๋ก์๊ฒ ์ํฅ์ ์ค ์ ์๋ค.
์ด๋ก ์ธํด ์ฅ์ ๋ ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ ์ ์๋ค. - ์ด๋ฌํ ์ผ์ ๋ฐฉ์งํ๊ธฐ ์ํด ํ Thread๊ฐ ์งํ ์ค์ธ ์์ ์ ๋ค๋ฅธ Thread๊ฐ ์นจ๋ฒํ์ง ๋ชปํ๋๋ก ๋ง๋ ๊ฒ์ด๋ค.
- ๋๊ธฐํ๋ฅผ ํ๋ ค๋ฉด ๋ค๋ฅธ Thread์ ์นจ๋ฒ์ ๋ง์์ผํ๋ ์ฝ๋๋ค์ '์๊ณ์์ญ'์ผ๋ก ์ค์ ํ๋ฉด ๋๋ค.
- ์๊ณ์์ญ์๋ Lock์ ๊ฐ์ง ๋จ ํ๋์ Thread๋ง ์ถ์
์ด ๊ฐ๋ฅํ๋ค.
- ์๊ณ์์ญ์ ํ๋ฒ์ ๋จ ํ๋์ Thread๋ง ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
- ์คํํ ๋ฉ์๋ ๋๋ ์คํํ ์ฝ๋ ๋ฌถ์ ์์ ๋ถ์ฌ์ ์๊ณ์์ญ์ ์ง์ ํ์ฌ ๋ค๋ฅธ Thread์ ์นจ๋ฒ์ ๋ง์ ์ ์๋ค.
package week05.thread.stat.sync;
public class Main {
public static void main(String[] args) {
AppleStore appleStore = new AppleStore();
Runnable task = () -> {
while (appleStore.getStoredApple() > 0) {
appleStore.eatApple();
System.out.println("๋จ์ ์ฌ๊ณผ์ ์ = " + appleStore.getStoredApple());
}
};
// 3๊ฐ์ thread๋ฅผ ํ๊บผ๋ฒ์ ๋ง๋ค์ด์ start๋ฅผ ํด๋ฒ๋ฆผ!!
// ์์ฑ(NEW)๊ณผ ๋์์ start(NEW -> Runnable)
for (int i = 0; i < 3; i++) {
// thread A, B, C
new Thread(task).start();
}
}
}
class AppleStore {
private int storedApple = 10;
public int getStoredApple() {
return storedApple;
}
public void eatApple() {
synchronized (this) {
if(storedApple > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
storedApple -= 1;
}
}
}
}
wait( ), notify( ) → ๋์ ์์ด๋ค. ํญ์ ๊ฐ์ด ์ฌ์ฉํ๋ค.
- ์นจ๋ฒ์ ๋ง์ ์ฝ๋(sync)๋ฅผ ์ํํ๋ค๊ฐ ์์ ์ ๋ ์ด์ ์งํํ ์ํฉ์ด ์๋๋ฉด, wait( )์ ํธ์ถํ์ฌ Thread๊ฐ Lock์ ๋ฐ๋ฉํ๊ณ ๊ธฐ๋ค๋ฆฌ๊ฒ ํ ์ ์๋ค.
- ์ถํ์ ์์ ์ ์งํํ ์ ์๋ ์ํฉ์ด ๋๋ฉด notify( )๋ฅผ ํธ์ถํด์ ์์ ์ ์ค๋จํ๋ Thread๊ฐ ๋ค์ Lock์ ์ป์ด ์งํํ ์ ์๊ฒ ๋๋ค.
wait( )
- ์คํ ์ค์ด๋ Thread๋ ํด๋น ๊ฐ์ฒด์ ๋๊ธฐ์ค(waiting pool)์์ ํต์ง๋ฅผ ๊ธฐ๋ค๋ฆฐ๋ค.
notify( )
- ํด๋น ๊ฐ์ฒด์ ๋๊ธฐ์ค(waiting pool)์ ์๋ ๋ชจ๋ Thread ์ค์์ ์์์ Thread๋ง ํต์ง๋ฅผ ๋ฐ๋๋ค. (random์ผ๋ก ๋ฐ๋๋ค.)
package week05.thread.stat.waitnotify;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static String[] itemList = {
"MacBook", "IPhone", "AirPods", "iMac", "Mac mini"
};
public static AppleStore appleStore = new AppleStore();
public static final int MAX_ITEM = 5;
public static void main(String[] args) {
// ๊ฐ๊ฒ ์ ์
Runnable StoreClerk = () -> {
while (true) {
// 0๋ถํฐ 4 ์ฌ์ด์ ์ ์ ์ค, Randomํ ๊ฐ์ ๋ฝ์๋ด๊ธฐ ์ํจ.
int randomItem = (int) (Math.random() * MAX_ITEM);
// restock : ์ฌ๊ณ ๋ฅผ ๋ฃ๋ ๋ฉ์๋
appleStore.restock(itemList[randomItem]);
try {
Thread.sleep(50);
} catch (InterruptedException ignored) {
}
}
};
// ๊ณ ๊ฐ
Runnable Customer = () -> {
while (true) {
try {
Thread.sleep(77);
} catch (InterruptedException ignored) {
}
int randomItem = (int) (Math.random() * MAX_ITEM);
// sale : ํ๋งคํ๋ ๋ฉ์๋
appleStore.sale(itemList[randomItem]);
System.out.println(Thread.currentThread().getName() + " Purchase Item " + itemList[randomItem]);
}
};
new Thread(StoreClerk, "StoreClerk").start();
new Thread(Customer, "Customer1").start();
new Thread(Customer, "Customer2").start();
}
}
class AppleStore {
private List<String> inventory = new ArrayList<>();
public void restock(String item) {
synchronized (this) {
while (inventory.size() >= Main.MAX_ITEM) {
System.out.println(Thread.currentThread().getName() + " Waiting!");
try {
wait(); // ์ฌ๊ณ ๊ฐ ๊ฝ ์ฐจ์์ด์ ์ฌ์
๊ณ ํ์ง ์๊ณ ๊ธฐ๋ค๋ฆฌ๋ ์ค!
Thread.sleep(333);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// ์ฌ์
๊ณ
inventory.add(item);
notify(); // ์ฌ์
๊ณ ๋์์์ ๊ณ ๊ฐ์๊ฒ ์๋ ค์ฃผ๊ธฐ
System.out.println("Inventory ํํฉ: " + inventory.toString());
}
}
public synchronized void sale(String itemName) {
while (inventory.size() == 0) {
System.out.println(Thread.currentThread().getName() + " Waiting!");
try {
wait(); // ์ฌ๊ณ ๊ฐ ์๊ธฐ ๋๋ฌธ์ ๊ณ ๊ฐ ๋๊ธฐ์ค
Thread.sleep(333);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while (true) {
// ๊ณ ๊ฐ์ด ์ฃผ๋ฌธํ ์ ํ์ด ์๋์ง ํ์ธ
for (int i = 0; i < inventory.size(); i++) {
if (itemName.equals(inventory.get(i))) {
inventory.remove(itemName);
notify(); // ์ ํ ํ๋ ํ๋ ธ์ผ๋ ์ฌ์
๊ณ ํ๋ผ๊ณ ์๋ ค์ฃผ๊ธฐ
return; // ๋ฉ์๋ ์ข
๋ฃ
}
}
// ๊ณ ๊ฐ์ด ์ฐพ๋ ์ ํ์ด ์์ ๊ฒฝ์ฐ
try {
System.out.println(Thread.currentThread().getName() + " Waiting!");
wait();
Thread.sleep(333);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Lock
- synchronized ๋ธ๋ญ์ผ๋ก ๋๊ธฐํํ๋ฉด ์๋์ ์ผ๋ก Lock์ด ๊ฑธ๋ฆฌ๊ณ ํ๋ฆฌ์ง๋ง, ๊ฐ์ ๋ฉ์๋ ๋ด์์๋ง Lock์ ๊ฑธ ์ ์๋ค๋ ์ ์ฝ์ด ์๋ค.
์ด ์ ์ฝ์ ํด๊ฒฐํ๊ธฐ ์ํด Lock ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ค. - ReentrantLock
- ์ฌ์ง์ ๊ฐ๋ฅํ Lock, ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฐฐํ Lock
- ํน์ ์กฐ๊ฑด์์ Lock์ ํ๊ณ , ๋์ค์ ๋ค์ Lock์ ์ป์ด ์๊ณ์์ญ์ผ๋ก ์ง์ ์ด ๊ฐ๋ฅํ๋ค.
public class MyClass {
private Object lock1 = new Object();
private Object lock2 = new Object();
public void methodA() {
synchronized (lock1) {
methodB();
}
}
public void methodB() {
synchronized (lock2) {
// do something
methodA();
}
}
}
- methodA์์ ์ด๋ฏธ Lock1์ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก lock2๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ์ํ๊ฐ ๋์ด ๋ฐ๋๋ฝ์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
- ํ์ง๋ง ReentrantLock์ ์ฌ์ฉํ๋ฉด, ๊ฐ์ Thread๊ฐ ์ด๋ฏธ Lock์ ๊ฐ์ง๊ณ ์๋๋ผ๋ Lock์ ์ ์งํ๋ฉฐ ๊ณ์ ์คํํ ์ ์๊ธฐ ๋๋ฌธ์ Dead-Lock์ด ๋ฐ์ํ์ง ์๋๋ค.
- ์ฝ๋์ ์ ์ฐ์ฑ์ ๋์ผ ์ ์๋ค.
- ReentrantReadWriteLock
- ์ฝ๊ธฐ๋ฅผ ์ํ Lock๊ณผ ์ฐ๊ธฐ๋ฅผ ์ํ Lock์ ๋ฐ๋ก ์ ๊ณตํ๋ค.
- ์ฝ๊ธฐ์๋ ๊ณต์ ์ ์ด๊ณ , ์ฐ๊ธฐ์๋ ๋ฒ ํ์ ์ธ Lock์ด๋ค.
- ์ฝ๊ธฐ Lock์ด ๊ฑธ๋ ค์์ผ๋ฉด ๋ค๋ฅธ Thread๋ค๋ ์ฝ๊ธฐ Lock์ ์ค๋ณต์ผ๋ก ๊ฑธ๊ณ ์ฝ๊ธฐ๋ฅผ ์ํํ ์ ์๋ค. (read-only)
- ์ฝ๊ธฐ Lock์ด ๊ฑธ๋ ค์๋ ์ํ์์ ์ฐ๊ธฐ Lock์ ๊ฑฐ๋ ๊ฒ์ ํ์ฉ๋์ง ์๋๋ค.
- StampedLock
- ReentrantReadWriteLock์ ๋๊ด์ ์ธ Lock์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ค.
- ๋๊ด์ ์ธ Lock : ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๊ธฐ ์ ์ ๋ฝ์ ๊ฑธ์ง ์๋ ๊ฒ์ ์๋ฏธํ๋ค.
- ๋๊ด์ ์ธ Lock์ ์ฌ์ฉํ๋ฉด ์ฝ๊ธฐ์ ์ฐ๊ธฐ ์์ ๋ชจ๋๊ฐ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌ๋๋ค. → ์ฌ๋ฌ Thread๊ฐ ๋์์ ๋ณ๊ฒฝํ๋ ค๊ณ ํ ๋๋ ์ ํฉํ์ง ์๋ค.
- ReentrantReadWriteLock์ ๋๊ด์ ์ธ Lock์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ค.
Condition
- waiting pool ๋ด Thread๋ฅผ ๊ตฌ๋ถํ์ง ๋ชปํ๋ค๋ ๊ฒ์ ํด๊ฒฐํ ๊ฒ์ด Condition์ด๋ค.
- Condition์ waiting pool ๋ด์ Thread๋ฅผ ๋ถ๋ฆฌํ์ฌ ํน์ ์กฐ๊ฑด์ด ๋ง์กฑ๋ ๋๋ง ๊นจ์ฐ๋๋ก ํ ์ ์์ผ๋ฉฐ, ReentrantLock ํด๋์ค์ ํจ๊ป ์ฌ์ฉ๋๋ค.
- ๋ฐ๋ผ์ Condition์ ์ฌ์ฉํ๋ฉด wait( )๊ณผ notify( )์ ๋ฌธ์ ์ ์ ๋ณด์ํ ์ ์๋ค.
public class Main {
public static final int MAX_TASK = 5;
private ReentrantLock lock = new ReentrantLock();
// lock์ผ๋ก condition ์์ฑ
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private ArrayList<String> tasks = new ArrayList<>();
// ์์
๋ฉ์๋
public void addMethod(String task) {
lock.lock(); // ์๊ณ์์ญ ์์
try {
while(tasks.size() >= MAX_TASK) {
String name = Thread.currentThread().getName();
System.out.println(name+" is waiting.");
try {
condition1.await(); // wait(); condition1 ์ฐ๋ ๋๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ฒ ํฉ๋๋ค.
Thread.sleep(500);
} catch(InterruptedException e) {}
}
tasks.add(task);
condition2.signal(); // notify(); ๊ธฐ๋ค๋ฆฌ๊ณ ์๋ condition2๋ฅผ ๊นจ์์ค๋๋ค.
System.out.println("Tasks:" + tasks.toString());
} finally {
lock.unlock(); // ์๊ณ์์ญ ๋
}
}
}
๋ชจ๋ ์๋ฐ ์์๋ณด๊ธฐ
- ์์ฅ์์ ํ๋ก๊ทธ๋๋จธ๊ฐ ํด๊ฒฐํด์ผ ํ๋ ๋ฌธ์ ๋ ๊ณ์ ๋ณํํ๋ค.
- ๋ฌธ์ ๊ฐ ๋ณํํ๊ธฐ ๋๋ฌธ์, ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ์๊ตฌ๋๋ ๊ธฐ๋ฅ๋ค๋ ๋ณํํ๋ค.
- ์๋ฅผ ๋ค์ด C/C++ ๊ฐ์ ์ธ์ด๋ค์ ํ๋ก๊ทธ๋จ ์คํ์ ๋ํ ๋น์ฉ์ด ํฌ์ง ์๊ณ , ํ๋์จ์ด์ ์ธ ๋ณดํธ์ฑ, ํธํ์ฑ์ ํฐ ์ฅ์ ์ ๊ฐ์ง๊ณ ์์๊ธฐ ๋๋ฌธ์ ์์ฅ์์ ๊ฐ์ฅ ์ง๋ฐฐ์ ์ธ ์ ์ง๋ฅผ ์ฐจ์งํ์์ต๋๋ค.
- ํ์ง๋ง ํน์ ์ ๋์ด๋์ ๋ค๋ฅธ ์์ธ๋ค์ ์ํฅ์ผ๋ก ์๊ธฐ์น ์๊ฒ ์ข ๋ฃ๋๊ฑฐ๋, ๋ณด์ ์ด์๊ฐ ๋ง์์ง๋ ๋ฑ ์์ ์ฑ์ด ๋จ์ด์ง๊ฒ ๋ฉ๋๋ค.
- ๊ทธ๋ฌ๋ ์์ค์ ํ๋์จ์ด๋ ๊พธ์คํ ์งํ๋ฅผ ๊ฑฐ๋ญํ๊ณ , ๊ทธ ์งํ์ ๊ฒฐ๊ณผ๋ก ํ๋ก๊ทธ๋จ์ ์คํ์ํค๋ ์์์ ๋ ๋ง์ด ์ฌ์ฉํด๋ ๊ด์ฐฎ์ ํ๊ฒฝ์์๋, ๋ ์์ ์ฑ์ด ๋์ c#, java์ ๊ฐ์ ์ธ์ด๋ค์ด ๊ฐ๊ด๋ฐ๊ฒ ๋ฉ๋๋ค.
- ์ด์ฒ๋ผ ์์ฅ์ ์ํฉ์ ๋ฐ๋ผ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ์๋ก์ด ๋์์ผ๋ก ๋ฑ์ฅํ๊ณ , ์ ์ํด์ ์ด์๋จ๊ฑฐ๋, ์ ์ํ์ง ๋ชปํด์ ๋ํ๋๊ธฐ๋ ํฉ๋๋ค.
๋๋ค ์ต๋ช ํจ์
- ๋๋ค๋ ์ต๋ช ํจ์๋ฅผ ์ง์นญํ๋ ๋ง์ด๋ค.
- ์ผ๊ธ ๊ฐ์ฒด๋ก ์ทจ๊ธ๋๋ค. → ์ผ๊ธ ๊ฐ(ํจ์ = ๊ฐ์ฒด(๋ณ์))์ผ๋ก ๋ฐ๋๋ค๋ ๊ฒ๊ณผ ๊ฐ์ ๋งฅ๋ฝ
์คํธ๋ฆผ
- ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ฐ์ฐ์ ์ง์ํ๋๋ก ์์ค์์ ์ถ์ถ๋ ์ฐ์๋ ์์์ด๋ค.
- ์ปฌ๋ ์ ์ ๋ฐ๋ณต์ ๋ฉ์ง๊ฒ ์ฒ๋ฆฌํ๋ ์ผ์ข ์ ๊ธฐ๋ฅ์ด์, Multi Thread ๊ด๋ จ ์ฝ๋๋ฅผ ๊ตฌํํ์ง ์์๋ ์์์ ๋ณ๋ ฌ๋ก ์ถ๊ฐํด์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค.
์ฌ์ฉ ์์ ์ฝ๋
package week05.thread.modern;
import java.util.ArrayList;
import java.util.List;
// ์ฃผ์ฐจ์ฅ ์์
// ํฐ์ผ, ํํน๋จธ๋ -> ์ฃผ์ฐจํ๊ฒ ํ๋ ์์
public class LambdaAndStream {
public static void main(String[] args) {
// ์ฃผ์ฐจ๋์ ์ฐจ๋
ArrayList<Car> carsWantToPark = new ArrayList<>();
// ์ฃผ์ฐจ์ฅ
ArrayList<Car> parkingLot = new ArrayList<>();
// ์ฃผ๋ง์ฃผ์ฐจ์ฅ
ArrayList<Car> weekendParkingLot = new ArrayList<>();
// 5๊ฐ์ car instance
Car car1 = new Car("Benz", "Class E", true, 0);
Car car2 = new Car("BMW", "Series 7", false, 100);
Car car3 = new Car("BMW", "X9", false, 0);
Car car4 = new Car("Audi", "A7", true, 0);
Car car5 = new Car("Hyundai", "Ionic 6", false, 10000);
carsWantToPark.add(car1);
carsWantToPark.add(car2);
carsWantToPark.add(car3);
carsWantToPark.add(car4);
carsWantToPark.add(car5);
// parkingLot.addAll(parkingCarWithTicket(carsWantToPark));
parkingLot.addAll(parkCars(carsWantToPark, Car::hasTicket));
// parkingLot.addAll(parkingCarWithMoney(carsWantToPark));
parkingLot.addAll(parkCars(carsWantToPark, Car::noTicketHasMoney));
// ์ต๋ช
ํจ์ ์ ์ฉ
parkingLot.addAll(parkCars(carsWantToPark, (Car car) -> car.hasParkingTicket() && car.getParkingMoney() > 1000));
for (Car car : parkingLot) {
System.out.println("Parked Car : " + car.getCompany() + "-" + car.getModel());
}
}
// ํ์
!!! -> (ํจ์ํ) ์ธํฐํ์ด์ค
// ์ธํฐํ์ด์ค๋ ํ์
์ญํ ์ ํ ์ ์๊ธฐ ๋๋ฌธ! (๋ฉํฐ ๋ฆฌ๋ชจ์ปจ ์์ )
// ํจ์ํ ์ธํฐํ์ด์ค : ์ถ์ ๋ฉ์๋๋ฅผ ๋ฑ ํ๋๋ง ๊ฐ์ง๊ณ ์๋ค!
// public exampleMethod (int parameter1, ??? parameterFunction) {
// parameterFunction~~~
// }
// public static List<Car> parkingCarWithTicket(List<Car> carsWantToPark) {
// ArrayList<Car> cars = new ArrayList<>();
//
// for (Car car : carsWantToPark) {
// if (car.hasParkingTicket()) {
// cars.add(car);
// }
// }
//
// return cars;
// }
//
// public static List<Car> parkingCarWithMoney(List<Car> carsWantToPark) {
// ArrayList<Car> cars = new ArrayList<>();
//
// for (Car car : carsWantToPark) {
// if (!car.hasParkingTicket() && car.getParkingMoney() > 1000) {
// cars.add(car);
// }
// }
//
// return cars;
//
// }
// ์์ ๋ ๋ฉ์๋๋ฅผ ํ๋๋ก!! : ๋ด๋ถ ์ฃผ์ ๋ก์ง์ ํจ์๋ก ์ ๋ฌ๋ฐ์
public static List<Car> parkCars(List<Car> carsWantToPark, Predicate<Car> function) {
List<Car> cars = new ArrayList<>();
for (Car car : carsWantToPark) {
// ์ ๋ฌ๋ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํ
if (function.test(car)) {
cars.add(car);
}
}
return cars;
}
}
class Car {
private final String company; // ์๋์ฐจ ํ์ฌ
private final String model; // ์๋์ฐจ ๋ชจ๋ธ
private final boolean hasParkingTicket;
private final int parkingMoney;
public Car(String company, String model, boolean hasParkingTicket, int parkingMoney) {
this.company = company;
this.model = model;
this.hasParkingTicket = hasParkingTicket;
this.parkingMoney = parkingMoney;
}
public String getCompany() {
return company;
}
public String getModel() {
return model;
}
public boolean hasParkingTicket() {
return hasParkingTicket;
}
public int getParkingMoney() {
return parkingMoney;
}
public static boolean hasTicket (Car car) {
return car.hasParkingTicket;
}
public static boolean noTicketHasMoney (Car car) {
return !car.hasParkingTicket && car.getParkingMoney() > 1000;
}
}
interface Predicate<T> {
boolean test(T t);
}
์ค๋ ํ๋ฃจ ์ ๋ฆฌโ๏ธ
ํ๋ฃจ์ข
์ผ ์๋ฐ ๊ฐ์ ๋ค์ผ๋ฉด์ ์ค์ต๋ง ํ๋ ๊ฒ ๊ฐ๋ค. Thread ๋ถ๋ถ์ ์ด๋ ์ ๋ ์ดํด๊ฐ ๋๋๋ฐ ๋ชจ๋ ์๋ฐ์ ์๋ ๋๋ค, ์คํธ๋ฆผ์ ๋ํด์๋ ์ถ๊ฐ์ ์ผ๋ก ๊ณต๋ถํ๋ฉด์ ์ตํ์ผ ํ ๊ฒ ๊ฐ๋ค!
์ค๋ 5์ฃผ์ฐจ ์์ ๊น์ง ๋๋ด๋ ๊ฒ์ด ๋ชฉํ์๋๋ฐ ๊ฐ์๋ฅผ ๋๋ฌด ์ค๋ ๋ค์ด์ ๋ด์ผ ์ค์ ์ผ๋ก ๋ฏธ๋ค์ผ๊ฒ ๋ค.. ์ค์ ์๋ ์์ ๋ฅผ ๋๋ด๋ ๊ฒ์ ๋ชฉํ๋ก ํ๊ณ ์คํ๋ถํฐ๋ ์ถ๊ฐ ๊ณผ์ (ํค์ค์คํฌ)๋ฅผ ๋์ ํด์ผ๊ฒ ๋ค!!
์ด๋ฒ ์ผ์ฃผ์ผ๋ ๊ณต๋ถ ์ด์ฌํ ํ๋ฉด์ ์ ๋ฒํด ๊ฒ ๊ฐ๋ค. ๊ณ์ํด์ ์ฑ์ฅํ๊ณ ์๊ณ ์ด๋๋ก ์ง์น์ง ์๊ณ ๊ณ์ ํด๋๊ฐ๋ค๋ฉด ์ข์ ์ฑ๊ณผ๋ฅผ ์ป์ ์ ์์ ๊ฒ ๊ฐ๋ค. ์ฒซ ๋ฒ์งธ ๊ณผ์ ์ธ ๊ณ์ฐ๊ธฐ ๋ง๋ค๊ธฐ์ ๋ํ ํํฐ๋์ ํผ๋๋ฐฑ์ ์ค๋ ํ์ธํ๋๋ฐ ์๊ฐ๋ณด๋ค ๊ธ์ ์ ์ผ๋ก ํผ๋๋ฐฑ์ ๋จ๊ฒจ์ฃผ์
์ ํค์ค์คํฌ ๊ณผ์ ์๋ ํผ๋๋ฐฑ์ ๋ฐ์ํด์ ๊ณผ์ ๋ฅผ ์์ฑํด์ผ๊ฒ ๋ค!!
์ฃผ๋ง์ด๋ผ๊ณ ๋์ด์ง์ง ๋ง๊ณ ์ ๋นํ ๊ณต๋ถํ๋ฉด์ ์ฌ์ด๊ฐ๋ ์๊ฐ์ ๊ฐ์ ธ์ผ์ง~~
์ด๋ฒ ์ฃผ๋ ๊ณ ์ํ๋ค..!!
๋ด์ผ ๊ณํโฐ
์ค์
- Java ๋ฌธ๋ฒ ์ข ํฉ๋ฐ_5์ฃผ์ฐจ ์์ ๋์ ..!
์คํ
- ํค์ค์คํฌ ๊ณผ์ ์์
- ์ธํ๋ฐ ๊ฐ์ ๋ค์ผ๋ฉด์ ๋ถ์กฑํ ๋ถ๋ถ ์ดํด
'Today I Learned(TIL) > ์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ํ๋ก๊ทธ๋๋ฐ ๊ธฐ์ด_Day 15 (0) | 2024.11.26 |
---|---|
ํ๋ก๊ทธ๋๋ฐ ๊ธฐ์ด_Day 13 (4) | 2024.11.23 |
ํ๋ก๊ทธ๋๋ฐ ๊ธฐ์ด_Day 11 (1) | 2024.11.22 |
ํ๋ก๊ทธ๋๋ฐ ๊ธฐ์ด_Day 10 (3) | 2024.11.20 |
ํ๋ก๊ทธ๋๋ฐ ๊ธฐ์ด_Day 9 (0) | 2024.11.20 |