: ํ๋์ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ ๊ฐ์ thread๊ฐ ๊ณต์ฉ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ๋ค.
ex) ์ํ ์ข์ ์ ๋ณด
์ฌ๋ฌ ๊ฐ์ thread๊ฐ ๊ณต์ ์์์ ์ ๊ทผํ ๋ ๋๊ธฐํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
ํ ์ฌ๋์ด ์ํ ์ข์์ ์๋งคํ๋ ๋์ ๋ค๋ฅธ ์ฌ๋์ด ๊ฒฐ์ ์๋ฃ๋ฅผ ํ๋ฉด ์๋ฆฌ๋ฅผ ๋บ๊ธด๋ค.
=> T1 thread๊ฐ ๊ฒฐ์ ๋ฅผ ํ๋ ๋์ ๋ค๋ฅธ thread์์ writing์ ํ ์ ์๊ฒ ํด์ค์ผ ํ๋ค.
=> Critical Section (์๊ณ ์์ญ)์ ์ค์ ํ๋ค.
-> Lock(Monitor) ๊ฐ๋
๋ฑ์ฅ
: T1 thread๊ฐ ์ฌ์ฉํ ๋๋ Lock์ ๊ฐ์ ธ๊ฐ๊ฒ ๋๋ฉด์ ์๊ณ ์์ญ์ ์ค์ ํ๋ค. T1 thread๊ฐ Lock์ ๋ค ์ด ํ์๋ ๋๋ ค์ค๋ค. ๋๊ธฐํ๋ thread๋ค ์ค ํ๋์ thread๊ฐ Lock์ ์ก๋๋ค.
package lecture0715;
// Thread์ ์ํด์ ๊ณต์ ๋๋ ๊ณต์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ์ํ class
class Account {
private int balance = 1000; // ๊ณ์ข ์์ก
public int getBalance() {
return balance;
}
// ์ถ๊ธํ๋ method
public 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; // 100๋ณด๋ค ๊ฐ๊ฑฐ๋ ํฌ๊ณ 400๋ณด๋ค ์์ ์ ์
acc.withdraw(money);
System.out.println("๋จ์ ์์ก์ : " + acc.getBalance());
}
}
}
public class ThreadExam09 {
public static void main(String[] args) {
ThreadEx_09 r = new ThreadEx_09();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
}
}
: ๋๊ฐ์ ์ฝ๋๊ฐ ๋์์ ์ง์ ํด์ ๋์์ ๊ณ์ข์ ๋์ ์ถ๊ธํ๊ฒ ๋๋ค.
: ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ๋ค.
method ๋๊ธฐํ
๋๊ธฐํ block์ ์์ฑ
: ํจ์จ์ด ๋ ์ข๋ค.
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; // 100๋ณด๋ค ๊ฐ๊ฑฐ๋ ํฌ๊ณ 400๋ณด๋ค ์์ ์ ์
acc.withdraw(money);
System.out.println("๋จ์ ์์ก์ : " + acc.getBalance());
}
}
}
public class ThreadExam09 {
public static void main(String[] args) {
ThreadEx_09 r = new ThreadEx_09();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
}
}
: method ์์ฒด๊ฐ ๋๊ธฐํ๊ฐ ๋์๋ค. ํ๋์ thread๊ฐ method๋ฅผ ์ํํ๋ ๋์ ๋ค๋ฅธ thread๋ method๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ํ์ง๋ง method ์์์ ๋๊ธฐํ๊ฐ ํ์ํ ๋ถ๋ถ์ ์ผ๋ถ๋ถ์ด๋ค. method ์์ฒด๋ฅผ ๋๊ธฐํ ์ฒ๋ฆฌ ํ๋ ๊ฒ์ ๋นํจ์จ์ ์ด๋ค.
package lecture0715;
// 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;
}
}
}
}
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; // 100๋ณด๋ค ๊ฐ๊ฑฐ๋ ํฌ๊ณ 400๋ณด๋ค ์์ ์ ์
acc.withdraw(money);
System.out.println("๋จ์ ์์ก์ : " + acc.getBalance());
}
}
}
public class ThreadExam09 {
public static void main(String[] args) {
ThreadEx_09 r = new ThreadEx_09();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
}
}
: ๋๊ธฐํ ์ฒ๋ฆฌ ํ ๋ถ๋ถ๋ง ๋ธ๋ก์ผ๋ก ๋ฌถ์ด์ค๋ค.
mutex : ์ด๋ค ๊ฐ์ฒด๋ฅผ ๋๊ธฐํ ํ ์ง ์ค์ ํด์ค๋ค.
thread๊ฐ ๊ณต์ ์์์ ๋ํ Lock์ ํ๋ํ ํ ์ค๋ ์๊ฐ์ ๋ณด๋ธ๋ค. -> ๋ค๋ฅธ thread๊ฐ ์ผ์ ๋ชป ํ๊ธฐ ๋๋ฌธ์ ๋ ๊ฐ์ง method๊ฐ ์ ๊ณต๋๋ค.
=> wait(), notify()
: Lock์ ๋๊ณ ๋๊ธฐ ์ํ๋ก ๋์๊ฐ๋ค.
: ๋๊ธฐ ์ํ์ ์๋ thread๊ฐ ์คํ๋ ์ ์๋๋ก block์ ํด์ ํ๋ค.
package lecture0715;
class ThreadEx_10 implements Runnable {
@Override
public void run() {
synchronized (this) {
try {
for(int i=0; i<20; i++) {
this.notify();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
this.wait();
}
} catch (Exception e) {
}
}
}
}
public class ThreadExam10 {
public static void main(String[] args) {
ThreadEx_10 r = new ThreadEx_10();
Thread t1 = new Thread(r, "1 Thread");
Thread t2 = new Thread(r, "2 Thread");
t1.start();
t2.start();
}
}
๋๋์ง ์๊ณ , ๊ณ์ํด์ ์ถ๋ ฅ๋๋ ๋ฌธ์ ๋ฐ์
package lecture0715;
class Shared {
public synchronized void printNum() {
try {
for(int i=0; i < 10; i++) {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " : " + i);
notify();
wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ThreadEx_10 implements Runnable {
private Shared shared;
public ThreadEx_10(Shared shared) {
this.shared = shared;
}
@Override
public void run() {
shared.printNum();
}
}
public class ThreadExam10 {
public static void main(String[] args) {
Shared obj = new Shared();
Thread t1 = new Thread(new ThreadEx_10(obj));
Thread t2 = new Thread(new ThreadEx_10(obj));
t1.setName("์ฒซ๋ฒ์งธ Thread!!");
t2.setName("๋๋ฒ์งธ Thread!!");
t1.start();
t2.start();
}
}