์ค๋ ๋ฐฐ์ธ๊ฑฐ...๐
1. Thread๊ฐ ๋ฌด์์ธ๊ฐ?
2. ์ค์ํ ์ฉ์ด, class์ method
3. Network Server๋ฅผ ๋ง๋ค๊ธฐ ์ํด ํ์ฉ
๊ทธ๋ ์ง๋ ์๋ค. ์๋ํ๋ฉด ๊ฐ๊ฐ์ ์ค๋ ๋๋ง๋ค stack ์์ญ์ด ๋ฐ๋ก ํ ๋น๋๊ธฐ ๋๋ฌธ์ด๋ค. thread๊ฐ ๋ง์ผ๋ฉด ๋ง์์๋ก stack ์์ญ์ ์ชผ๊ฐ์ ์ฃผ์ด์ผ ํ๋ค. ์ด ์ ์์ resource๊ฐ ๋ถ์กฑํด์ง๊ฒ ๋๋ค. ๋ฐ๋ผ์ ์ ๋นํ ์์ด ์ข๋ค.
๋ง์ฝ ๋ด๊ฐ ์ฌ์ฉํ๋ ์ปดํจํฐ๊ฐ single core๋ผ๋ฉด, core๋ ํ๋์ธ๋ฐ ์ฌ๋ฌ๊ฐ์ ํ๋ก๊ทธ๋จ์ด ๋ง์น ๋์์ ์คํ๋๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค. ์ด๋ป๊ฒ..?
์๊ฐ์ ์ชผ๊ฐ์ ๋ง์น ๋์์ ์คํ๋๋ ๊ฒ์ฒ๋ผ ํ๋ ๊ฒ์ด๋ค. ์ด๋ Multi tasking (core์ ๊ฐ์์ ์๊ดX) ์ด๋ค.
์ง์ง ์ฌ๋ฌ๊ฐ์ ํ๋ก๊ทธ๋จ์ด ๋์์ ์คํ, core๊ฐ 2๊ฐ ์ด์์ผ๋๋ง ๊ฐ๋ฅํ๋ค.
ํ๋์ ํ๋ก๊ทธ๋จ์ด ์ฌ๋ฌ๊ฐ์ thread๊ฐ ์กด์ฌํ ๋, ์๊ฐ์ ๋์์ ์คํ๋๋ ๊ฒ์ฒ๋ผ ํ๋ ๊ฒ์ด๋ค.
[์ฅ์ ]
[๋จ์ ]
JVM์ด Thread๋ฅผ ์์ฑ -> Thread๊ฐ main( ) ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค.
- ๋ฉ์๋ ์์ฒด๋ฅผ Thread์ ๋์ผ์ํ๋ฉด ์๋๋ค.
- main( ) ๋ฉ์๋๋ main thread์ ์ํด์ ์คํ๋๋ค.
[ ๋ฐฉ๋ฒ 1 ]
[ ๋ฐฉ๋ฒ 2 ]
package lecture0714;
class MyThread extends Thread{
@Override
public void run() {
System.out.println("Hello");
}
}
public class Main {
public static void main(String[] args) {
MyThread t = new MyThread();
// t.run(); // ์ธ์คํด์ค์ ๋ฉ์๋ ํธ์ถ
t.start(); // 1. thread ์์ฑ 2. stack ํธ์ถ 3. run()ํธ์ถ
System.out.println("์๋
ํ์ธ์!");
// ์คํ ์์๋ฅผ ๋ณด์ฅํ์ง ๋ชปํ๋ค.
}
}
package lecture0714;
class MyThread extends Thread{
@Override
public void run() {
System.out.println("Hello");
}
}
class MyThread2 implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("์ด๊ฒ๋ ์คํ๋์!");
}
}
public class Main {
public static void main(String[] args) {
MyThread t = new MyThread();
// t.run(); // ์ธ์คํด์ค์ ๋ฉ์๋ ํธ์ถ
t.start();
MyThread2 a = new MyThread2();
Thread t1 = new Thread(a); // Thread ๊ฐ์ฒด์ ์ธ์ ๋๊ธฐ๊ธฐ -> ์ค์ Thread ๊ฐ์ฒด ๋ง๋ค๊ธฐ
t1.start();
System.out.println("์๋
ํ์ธ์!");
}
}
- thread ์์ฑ
- stack ํธ์ถ
- run( ) ํธ์ถ
์ด๋ค ๋ฉ์๋๊ฐ ๋จผ์ ์คํ๋ ์ง์ ๋ํด์๋ ์ค์ผ์ค๋ฌ์ ์ํด์ ๊ฒฐ์ ๋๋ค.
๋ฐ๋ผ์ ์ํ ์์๋ฅผ ๋ณด์ฅํ์ง ๋ชปํ๋ค.
package lecture0714;
class ThreadEx_01_1 extends Thread{
@Override
public void run() {
for (int i=0; i<5; i++) {
System.out.println(getName()); // ์ค๋ ๋์ ์ด๋ฆ์ ์์๋ด๋ ๋ฉ์๋
}
}
}
class ThreadEx_01_2 implements Runnable{
@Override
public void run() {
for (int i=0; i<5; i++) {
System.out.println(Thread.currentThread().getName());
// ์์ง ์ค๋ ๋๊ฐ ์๋์ฌ์ this.getName() ์ฌ์ฉ ๋ชปํจ.
// ์ค๋ ๋๊ฐ ๊ฐ์ง๊ณ ์๋ static ๋ฉ์๋ ์ฌ์ฉ
// ์ด ์ฝ๋๊ฐ ์คํ๋๋๋ฐ ํ์ฌ ์คํ๋๊ณ ์๋ ์ค๋ ๋๋ฅผ ์ง์นญํจ
}
}
}
public class ThreadExam01 {
public static void main(String[] args) {
ThreadEx_01_1 t1 = new ThreadEx_01_1();
ThreadEx_01_2 r = new ThreadEx_01_2();
Thread t2 = new Thread(r);
t1.start();
t2.start();
System.out.println("main thread ์ข
๋ฃ");
}
}
// ์ด๋ค ์ค๋ ๋๊ฐ ๋จผ์ ์คํ๋๋์ง ์ ์ ์๋ค.
// ์ค์ผ์ค๋ฌ์ ์ํด์ ์ ํ๋์ด์ ์คํ๋๊ธฐ ๋๋ฌธ์ ์ด๋ค๊ฒ ์ ํ๋๋์ง ์ ์ ์๋ค.
๋ด๋ถ์์ ํ์๋ ๋ชจ๋ user define thread๊ฐ ์ข ๋ฃ๋๋ ์๊ฐ process๊ฐ ์ข ๋ฃ๋๋ค.
์ผ์ชฝ ๊ทธ๋ฆผ์ single thread๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด๊ณ , ์ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์ 2๊ฐ์ thread๋ฅผ ์ด์ฉํด ์์ ์ ์ํํ๋ค.
์ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์ผ๋ก ์ํํ ๊ฒฝ์ฐ, ๋ ์์ ์ด ๋์์ ์คํ๋๋ ๊ฒ๊ณผ ๊ฐ์ ํจ๊ณผ๊ฐ ๋๋ค.
์๋๋ฉด์์ ์ผ์ชฝ ์ฌ์ง์ด ๋ ๋น ๋ฅด๋ค.
์? context switching์ด ์ผ์ด๋์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
public class ThreadExam01 {
public static void main(String[] args) {
ThreadEx_01_1 t1 = new ThreadEx_01_1();
ThreadEx_01_2 r = new ThreadEx_01_2();
Thread t2 = new Thread(r);
// multi-core ํ๊ฒฝ์์๋ ์ฐ์ ์์์ ์๋ฏธ๊ฐ ์๋ค
// (single core์์๋ง ์ ์ฉ๋๊ณ ์๋ฏธ์์)
// minimu = 0, maximum = 10 ํด์๋ก ์ฐ์ ์์๊ฐ ๋๋ค
t1.setPriority(10);
t2.setPriority(2);
t1.start();
t2.start();
System.out.println("main thread ์ข
๋ฃ");
}
}
๋ค๋ฅธ ์ผ๋ฐ Thread์ ๋ณด์กฐ์ ์ธ ์์ ์ ์ํด ์ฌ์ฉํ๋ค.
t1.setDaemon(true);
package lecture0714;
// Daemon Thread์ ๋ํด์ ์์๋ณด์์!
public class ThreadExam02 implements Runnable {
static boolean autoSave = false;
public static void main(String[] args) {
Thread t = new Thread(new ThreadExam02());
t.setDaemon(true); // ๋ฐ๋ชฌ ์ค๋ ๋๋ก ๋ฐ๊พธ์ด์ฃผ๊ธฐ
t.start();
for (int i=0; i<10; i++) {
try {
Thread.sleep(1000); // ํ์ฌ ์คํํ๊ณ ์๋ ์ค๋ ๋๋ฅผ ์ฌ์ (์ฌ๊ธฐ์๋ main ์ค๋ ๋๊ฐ sleep)
}catch(Exception e) {
}
System.out.println(i);
if (i == 5) {
autoSave = true;
}
}
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(3000); // t Thread๋ฅผ sleep ์ํด
} catch(InterruptedException e) {
}
if(autoSave) {
System.out.println("์๋์ ์ฅ๋์์ด์!");
}
}
}
}
- ์์ฑ
- start( )
- sleep( )
- stop( ) (์๋ 3๊ฐ ์ด์ ์ ์ โ)
1 ) stop( ) - Thread์ ์ข ๋ฃ(๊ฐ์ )
2 ) suspend( ) - Thread์ ์ผ์์ค์ง
3 ) resume( ) - ์ผ์์ค์ง๋ Thread์ ์ฌ์์- interrupt( ), interrupted( ) [ํ์ธ] , isInterrupted( ) [ํ์ธ]
- yield( )
package lecture0714;
class ThreadEx_03_1 extends Thread {
@Override
public void run() {
for(int i=0; i<300; i++) {
System.out.print("-");
}
System.out.println("<<Thread 1 ์ข
๋ฃ>>");
}
}
class ThreadEx_03_2 extends Thread {
@Override
public void run() {
for(int i=0; i<300; i++) {
System.out.print("|");
}
System.out.println("<<Thread 2 ์ข
๋ฃ>>");
}
}
public class ThreadExam03{
public static void main(String[] args) {
ThreadEx_03_1 t1 = new ThreadEx_03_1();
ThreadEx_03_2 t2 = new ThreadEx_03_2();
t1.start();
t2.start();
try {
t1.sleep(2000); // ํ์ฌ ์คํ๋๋ ์ค๋ ๋๋ฅผ ์ฌ์ฐ๋ ๊ฒ
// -> ํน์ ์ค๋ ๋๊ฐ ์๋ main ์ค๋ ๋๊ฐ ์ฌ์ฐ๊ฒ ๋จ
}catch (Exception e) {
}
System.out.println("<<main Thread ์ข
๋ฃ>>");
}
}
package lecture0714;
class ThreadEx_03_1 extends Thread {
@Override
public void run() {
try {
Thread.sleep(2000);
}catch (Exception e) {
}
for(int i=0; i<300; i++) {
System.out.print("-");
}
System.out.println("<<Thread 1 ์ข
๋ฃ>>");
}
}
class ThreadEx_03_2 extends Thread {
@Override
public void run() {
for(int i=0; i<300; i++) {
System.out.print("|");
}
System.out.println("<<Thread 2 ์ข
๋ฃ>>");
}
}
public class ThreadExam03{
public static void main(String[] args) {
ThreadEx_03_1 t1 = new ThreadEx_03_1();
ThreadEx_03_2 t2 = new ThreadEx_03_2();
t1.start();
t2.start();
System.out.println("<<main Thread ์ข
๋ฃ>>");
}
}
//2์ด ๋์ Thread1 ์๊ณ ์์
// main ์ค๋ ๋ ์คํ
// Thread2 ์คํ
// Thread1 ์คํ
- stop( ) -> thread ๊ฐ์ ์ค์ง -> X, ์ฌ์ฉ๋ถ๊ฐ ( deprecated )
- start( ) -> thread ์์! (์ด๊ฒ๋ง ์ฌ์ฉ๊ฐ๋ฅ)
thread ์คํ ํ ์์ ์ด ๋๋๊ธฐ ์ ์ ํด๋น thread๋ฅผ ์ค์ง์ํค๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
- interrupted( ) : Thread์ static (ํด๋์ค ๋ฉ์๋)
ํ์ฌ ์ํ์ค์ธ thread๊ฐ interrupt๊ฐ ๊ฑธ๋ ธ๋์ง ์์๋ณผ ์ ์๋ค. ํน์ ์ค๋ ๋๋ฅผ ์ง์นญํ ์ ์๋ค...
์ํ๊ฐ์ ์กฐ์ฌํ๊ณ ๊ทธ ์ํ๊ฐ์ false๋ก ๋ฐ๊พผ๋ค. (์กฐ์ฌ~๐โโ๏ธ)- isInterrupted( ) : static์ด ์๋๋ค.
ํน์ ์ค๋ ๋๋ฅผ ์ง์นญํด์ interrupt๊ฐ ๊ฑธ๋ ธ๋์ง ์ฌ๋ถ๋ฅผ ์ ์ ์๋ค
์ํ๊ฐ๋ง true/false๋ก return ํด์ค๋ค
package lecture0714;
import javax.swing.JOptionPane;
class ThreadEx_04 extends Thread{
@Override
public void run() {
int i = 10;
while (i != 0 && !isInterrupted()) {
System.out.println(--i);
// ์ด ๋ถ๋ถ ๋๋ฌด ๊ตฌ๋ ค์.. ๋ฐ์์ ๋ฐ๊ฟ๋ด์..!
for(long k=0; k<2500000000L; k++) { // ์๊ฐ์ง์ฐ
}
}
System.out.println("์นด์ดํธ๊ฐ ์ข
๋ฃ๋์์ด์");
}
}
public class ThreadExam04 {
public static void main(String[] args) {
Thread t = new ThreadEx_04();
t.start();
String input = JOptionPane.showInputDialog("๊ฐ์ ์
๋ ฅํ์ธ์!");
System.out.println("์
๋ ฅ๊ฐ์ : "+input);
t.interrupt();
// Thread t์ interrupt ์ํ๊ฐ true๊ฐ ๋๋ค.
System.out.println("Thread ์ํ๊ฐ์ : "+t.isInterrupted());
}
}
/*
9
8
7
6
5
4
3
์
๋ ฅ๊ฐ์ : 14
Thread ์ํ๊ฐ์ : true
์นด์ดํธ๊ฐ ์ข
๋ฃ๋์์ด์
*/
package lecture0714;
import javax.swing.JOptionPane;
class ThreadEx_04 extends Thread{
@Override
public void run() {
int i = 10;
while (i != 0 && !isInterrupted()) {
System.out.println(--i);
// for(long k=0; k<2500000000L; k++) { // ์๊ฐ์ง์ฐ
// }
// sleep ์ด์ฉํ ์ฝ๋๋ก ๋์ฒด ๊ฐ๋ฅํฉ๋๋ค~!
// ๊ทธ๋ฐ๋ฐ ๋ฌธ์ ๊ฐ ์๊น๋๋ค..
try {
Thread.sleep(4000);
// ์๊ณ ์์ ๋ interrupt๊ฐ ๊ฑธ๋ฆฐ๋ค.
// ์ผ์ด๋๊ฒ ๋๋ฉด ์๊ธฐ์ intrrupted ์ํ๋ฅผ false๋ก ์ด๊ธฐํ์ํจ๋ค.
// ๋ฐ๋ผ์ sleep์ ์ฌ์ฉํ๊ฒ ๋๋ฉด, ์ซ์๊ฐ ์ค๋จ๋์ง ์๊ณ ๊ณ์ ๋์๊ฐ๋ค.
} catch(Exception e) {
// interrupt๊ฐ false์ธ ์ํ๋ก ๋์ด ์๋ค.
// ๋ฐ๋ผ์ catch๋ฌธ์์ interrupt๋ฅผ ํ ๋ฒ ๋ ๊ฑธ์ด์ค์ผ ๋๋ค.
interrupt();
}
}
System.out.println("์นด์ดํธ๊ฐ ์ข
๋ฃ๋์์ด์");
}
}
public class ThreadExam04 {
public static void main(String[] args) {
Thread t = new ThreadEx_04();
t.start();
String input = JOptionPane.showInputDialog("๊ฐ์ ์
๋ ฅํ์ธ์!");
System.out.println("์
๋ ฅ๊ฐ์ : "+input);
t.interrupt();
// Thread t์ interrupt ์ํ๊ฐ true๊ฐ ๋๋ค.
System.out.println("Thread ์ํ๊ฐ์ : "+t.isInterrupted());
}
}
/*
9
8
7
6
5
4
3
์
๋ ฅ๊ฐ์ : 14
Thread ์ํ๊ฐ์ : true
2
1
์นด์ดํธ๊ฐ ์ข
๋ฃ๋์์ด์
*/
์ง๊ธ์ ์ฌ์ฉํ์ง ์์ ๋ฉ์๋๋ค.
ํ์ง๋ง ๋ก์ง์ ํ์
ํ๊ธฐ ์ํด ์ฝ๋๋ฅผ ์์ฑํด๋ณด์.
package lecture0714;
class ThreadEx_05 implements Runnable{
@Override
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
}catch(Exception e) {
}
}
}
}
public class ThreadExam05 {
public static void main(String[] args) {
ThreadEx_05 r = new ThreadEx_05();
// thread 3๊ฐ
Thread t1 = new Thread(r,"*"); // ๋ ๋ฒ์งธ ์ธ์๋ thread์ ์ด๋ฆ
Thread t2 = new Thread(r,"**");
Thread t3 = new Thread(r,"***");
t1.start();
t2.start();
t3.start();
try {
Thread.sleep(2000);
t1.suspend(); // t1์ ์ผ์ ์ค์ง
Thread.sleep(2000);
t2.suspend(); // t2๋ฅผ ์ผ์ ์ค์ง
Thread.sleep(2000);
t1.resume(); // t1์ด ๋ค์ ๋์ํ๋๋ก ์ค์
Thread.sleep(2000);
t1.stop();
t2.stop();
Thread.sleep(2000);
t3.stop();
} catch (Exception e) {
}
}
}
package lecture0714;
/* ๊ฐ์ ๋์ ๋ก์ง์ผ๋ก ๋ฐ๊ฟ๋ณด์ */
class ThreadEx_06 implements Runnable{
// boolean suspended = false;
// boolean stopped = false;
volatile boolean suspended = false;
volatile boolean stopped = false;
@Override
public void run() {
while(!stopped) {
if (!suspended) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
}catch(Exception e) {
}
}
}
}
public void suspend() {
suspended = true;
}
public void stop() {
stopped = true;
}
public void resume() {
suspended = false;
}
}
public class ThreadExam06 {
public static void main(String[] args) {
ThreadEx_06 r1 = new ThreadEx_06();
ThreadEx_06 r2 = new ThreadEx_06();
ThreadEx_06 r3 = new ThreadEx_06();
// thread 3๊ฐ
Thread t1 = new Thread(r1,"*"); // ๋ ๋ฒ์งธ ์ธ์๋ thread์ ์ด๋ฆ
Thread t2 = new Thread(r2,"**");
Thread t3 = new Thread(r3,"***");
t1.start();
t2.start();
t3.start();
try {
Thread.sleep(2000);
r1.suspend(); // t1์ ์ผ์ ์ค์ง
Thread.sleep(2000);
r2.suspend(); // t2๋ฅผ ์ผ์ ์ค์ง
Thread.sleep(2000);
r1.resume(); // t1์ด ๋ค์ ๋์ํ๋๋ก ์ค์
Thread.sleep(2000);
r1.stop();
r2.stop();
Thread.sleep(2000);
r3.stop();
} catch (Exception e) {
}
}
}
๋ก์ง์ ๋ฌธ์ ๊ฐ ์๋๋ฐ ์ฝ๋๊ฐ ์ผ๋ถ ์ด์ํ๊ฒ ๋์ํ๋ค.
๋ค์์ ๋ฉํฐ์ฝ์ด ํ๋ก์ธ์ค์์ ๋์ํ๋ ๋ก์ง์ด๋ค.
๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด cache๊ฐ ์๋ memory์์ ๋ณ์๋ฅผ ๊ฐ์ ธ์ค๋ผ๋ ํค์๋ ๋ถ๋๋ค.
Thread๊ฐ ์์ ์๊ฒ ์ฃผ์ด์ง ์คํ์๊ฐ์ ๋ค ์ฐ์ง์๊ณ ๋ค๋ฅธ Thread์๊ฒ ์๋ณดํด์ค๋ค.
package lecture0714;
/* ๊ฐ์ ๋์ ๋ก์ง์ผ๋ก ๋ฐ๊ฟ๋ณด์ */
class ThreadEx_06 implements Runnable{
volatile boolean suspended = false;
volatile boolean stopped = false;
@Override
public void run() {
while(!stopped) {
if (!suspended) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
}catch(Exception e) {
}
} else {
Thread.yield(); // ์๋ณด๋ฅผ ํตํด busy waiting์ ํผํ ์ ์๋ค.
}
}
}
public void suspend() {
suspended = true;
}
public void stop() {
stopped = true;
}
public void resume() {
suspended = false;
}
}
public class ThreadExam06 {
public static void main(String[] args) {
ThreadEx_06 r1 = new ThreadEx_06();
ThreadEx_06 r2 = new ThreadEx_06();
ThreadEx_06 r3 = new ThreadEx_06();
// thread 3๊ฐ
Thread t1 = new Thread(r1,"*"); // ๋ ๋ฒ์งธ ์ธ์๋ thread์ ์ด๋ฆ
Thread t2 = new Thread(r2,"**");
Thread t3 = new Thread(r3,"***");
t1.start();
t2.start();
t3.start();
try {
Thread.sleep(2000);
r1.suspend(); // t1์ ์ผ์ ์ค์ง
Thread.sleep(2000);
r2.suspend(); // t2๋ฅผ ์ผ์ ์ค์ง
Thread.sleep(2000);
r1.resume(); // t1์ด ๋ค์ ๋์ํ๋๋ก ์ค์
Thread.sleep(2000);
r1.stop();
r2.stop();
Thread.sleep(2000);
r3.stop();
} catch (Exception e) {
}
}
}
package lecture0715;
class ThreadEx_07_1 extends Thread{
@Override
public void run() {
for (int i=0; i<300; i++) {
System.out.print("-");
}
}
}
class ThreadEx_07_2 extends Thread{
@Override
public void run() {
for (int i=0; i<300; i++) {
System.out.print("|");
}
}
}
public class ThreadExam07 {
public static void main(String[] args) {
Thread t1 = new ThreadEx_07_1();
Thread t2 = new ThreadEx_07_2();
t1.start();
t2.start();
try {
// ๋ด๊ฐ ์ํ๋๋ ๊ฒ์ hold ์ํค๊ณ , ์ง์ ํ thread๊ฐ ๋์ํ๊ฒ ํจ
// ์คํ์ค์ธ main thread๋ฅผ ์ผ์์ ์ผ๋ก block์ํด
// blocked๋ thread๋ฅผ Runnable ์ํ๋ก ๋ณํ์ํค๊ธฐ ์ํด try-catch๋ฌธ ์ฌ์ฉํจ
t1.join();
t2.join();
} catch (Exception e) {
// TODO: handle exception
}
System.out.println("<<main>> ์ข
๋ฃ");
}
}
package lecture0715;
class ThreadEx_08_1 extends Thread{
final static int MAX_MEMORY = 1000;
int usedMemory = 0;
@Override
public void run() {
while(true) {
try {
Thread.sleep(10000); // 10์ด ๋์ ์์!
} catch (Exception e) {
System.out.println("interrupt์ ์ํด์ ๊นจ์ด๋ฌ์ด์!");
}
gc();
System.out.println("๋ฉ๋ชจ๋ฆฌ ์ฒญ์ ์๋ฃ! ํ์ฌ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ๋์:"
+ freeMemory());
}
}
public void gc() {
usedMemory -= 300;
if(usedMemory < 0) {
usedMemory = 0;
}
}
public int totalMemory() {
return MAX_MEMORY;
}
public int freeMemory() {
return MAX_MEMORY - usedMemory;
}
}
public class ThreadExam08 {
public static void main(String[] args) {
ThreadEx_08_1 t1 = new ThreadEx_08_1();
t1.setDaemon(true);
t1.start();
int requiredMemory = 0;
for(int i=0; i<20; i++) {
requiredMemory = ((int)(Math.random() * 10)) * 20;
// 0.0๋ณด๋ค ๊ฐ๊ฑฐ๋ ํฌ๊ณ 200๋ณด๋ค ์์ ์ ์
// ํ์ํ memory๊ฐ ์ฌ์ฉํ ์ ์๋ ์๋ณด๋ค ํฌ๊ฑฐ๋
// ํ์ฌ ์ ์ฒด ๋ฉ๋ชจ๋ฆฌ์์ 60%์ด์์ ์ฌ์ฉํ๊ณ ์์ ๋ gc๋ฅผ ์คํ
if ((t1.freeMemory() < requiredMemory) ||
(t1.freeMemory() < t1.totalMemory() * 0.4)) {
t1.interrupt(); // ์ฌ๊ธฐ์ gc() ์คํ์ด ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์์์!
try {
t1.join(100);
} catch (Exception e) {
// TODO: handle exception
}
}
// ์ฒญ์๊ฐ ๋์์ผ๋ ๋ฉ๋ชจ๋ฆฌ์์ ์ฌ์ฉํ ์ ์์
t1.usedMemory += requiredMemory;
System.out.println("์ฌ์ฉ๋ ๋ฉ๋ชจ๋ฆฌ๋ :" +t1.usedMemory);
}
}
}
ํ๋์ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ๊ฐ์ thread๊ฐ ๊ณต์ฉ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
T1์ด 1๋ฒ์ ์ ํํ๊ณ ์นด๋ ๊ฒฐ์ ํ๊ณ ์๋ ์์ค์๋ ๋ค๋ฅธ T๊ฐ ๋ฐฉํดํ์ง ๋ชปํ๋๋ก ๋ง์์ค์ผ ๋๋ค.
1 ) Critical section(์๊ณ ์์ญ)์ ์ค์ ํด์ฃผ์ด์ผ ํ๋ค.
2 ) Lock(Monitor)์ ๋์
ํด์ ์๊ณ ์์ญ์ ์ค์ ํ ์ ์๋ค.
- T1์ด Lock์ ๊ฐ์ ธ๊ฐ์ ๋ค๋ฅธ T๊ฐ ๊ณต์ฉ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ง ๋ชป ํ๋๋ก ํ๋ค.
- T1์ด ์์ ์ ๋๋ง์น๋ฉด Lock์ ๋ฐ๋ฉํ๊ณ , ๋๊ธฐ์ํ์ ์๋ ๋ค๋ฅธ T๊ฐ Lock์ ์ก๋๋ค.
- ํ๋ํ์ง ๋ชปํ ๋ค๋ฅธ T๋ ๋ ๋๊ธฐ๋ฅผ ํ๋ค.
- ๋ฐ๋ผ์ Lock์ ์ป์ด์ ์๊ณ์์ญ์ ์ค์ ํ ์ ์๋ค.
- Java์์ "Lock"์ ์ป์ด ์๊ณ์์ญ์ ์ค์ ํ๋ ค๋ฉด synchronized ํค์๋๋ฅผ ์ด์ฉํ๋ค.
package lecture0715;
// Thread์ ์ํด์ ๊ณต์ ๋๋ ๊ณต์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ์ํ class
class Account{
private int balance = 1000; //๊ณ์ข ์์ก
public int getBalance() {
return balance;
}
// ์ถ๊ธํ๋ method => ๋๊ธฐํ ์ฒ๋ฆฌ
public synchronized void withdraw(int money) {
if (balance >= money) {
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
balance -= money;
}
}
}
class ThreadEx_09 implements Runnable{
Account acc = new Account();
@Override
public void run() {
while(acc.getBalance()>0) {
int money = ((int)(Math.random() * 3 + 1)*100);
acc.withdraw(money);
System.out.println("๋จ์ ์์ก :" + acc.getBalance());
}
}
}
public class ThreadExam09 {
public static void main(String[] args) {
ThreadEx_09 r = new ThreadEx_09(); // runnable ๊ฐ์ฒด
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
}
}
๋ง์ฝ synchronized๋ ๋ฉ์๋์ ์ฝ๋๊ฐ ๊ธธ ๊ฒฝ์ฐ,
๋ฉ์๋ ์์๋ ๋๊ธฐํ๊ฐ ํ์ํ ์ฝ๋์ ๋ถํ์ํ ์ฝ๋๊ฐ ํผ์ฌํ๋ค.
๋ฐ๋ผ์ ํจ์จ์ ์ํด ๋๊ธฐํ๊ฐ ํ์ํ ๋ถ๋ถ๋ง ๋๊ธฐํ๋ฅผ ์์ผ ๋ฒ์๋ฅผ ์ค์ฌ์ค ์ ์๋ค.
์๋์ ๊ฐ์ ์ฝ๋๊ฐ ๊ทธ ์์ ์ ์ํํ ๋ถ๋ถ์ด๋ค.
// Thread์ ์ํด์ ๊ณต์ ๋๋ ๊ณต์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ์ํ class
class Account{
private int balance = 1000; //๊ณ์ข ์์ก
public int getBalance() {
return balance;
}
// ์ถ๊ธํ๋ method => ๋๊ธฐํ ์ฒ๋ฆฌ
public void withdraw(int money) {
// ๋๊ธฐํ ๋ธ๋ก
synchronized(this) { // ์ธ์์๋ ์ด๋ค ๊ฐ์ฒด์ ๋ํด ๋๊ธฐํ ํ ์ง
if (balance >= money) {
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
balance -= money;
}
}
}
}
Synchronized๋ฅผ ์ด์ฉํด์ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ๋ ๊ฒ์ ์ข์ ๋ถ๋ถ์ด๋ค.
ํ์ง๋ง Thread๊ฐ ๊ณต์ ์์์ ๋ํ Lock์ ํ๋ํ ํ ๋ณ๋ค๋ฅธ ์ผ์ ํ์ง์๊ณ ์ค๋์๊ฐ lock๋ง ๊ณ์ ๋ค๊ณ ์๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. ์ฆ, ๊ธฐ๋ค๋ฆฌ๊ณ ์๋ ๋ค๋ฅธ Thread์ ๋ํด์ starvation ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ 2๊ฐ์ง ๋ฉ์๋๊ฐ ์กด์ฌํ๋ค.
- wait( ) - Lock์ ๋๊ณ ์ผ์ ๋๊ธฐ ์ํ๋ก ๋์ผ ์ ์๊ฒ ํ๋ ๋ฉ์๋
- notify( ) - ๋๊ธฐ์ํ์ ์๋ Thread๊ฐ ์คํ๋ ์ ์๋๋ก block์ ํด์ ํ๋ ๋ฉ์๋