*스레드 : 명령처리 흐름
프로세스 : 프로그램이 실행되는 단위.
병렬처리하는 방법 : 멀티스레드, 멀티프로세스
멀티프로세스 - 각프로세스가 독립된 메모리를 가지기 때문에 어떻게 데이터를 공유할것인가각 이슈!
멀티스레드 - 두개이상의 명령흐름이 같은 데이터를 접근하기때문에 어떻게 제어할 것인가가 이슈!
스레드를 생성하는방법!
-Thread 클래스를 상속하는 방법
class Counting extends Thread{
public void run(){
for(int i = 0; i < 10; i ++)
System.out.println(i);
}
public static void main(String[] args) {
Thread t = new Counting();
t.start(); //스레드를 상속 받은 카운팅객체의 run메소드 실행.
-Runnable 인터페이스를 구현하는 방법
class Counting implements Runnable{
public void run(){
for(int i = 0; i < 10; i ++)
System.out.println(i);
System.out.println("파생 : " + Thread.currentThread().getId());
}
}
public class Test {
public static void main(String[] args) {
Counting c = new Counting();
Thread t = new Thread(c);
t.start();
System.out.println("메인 : " + Thread.currentThread().getId());
}
}
*동기화 : 한번에 하나의 스레드만이 공유 데이터를 접근할 수 있도록 제어하는것이 필요.
ex)
public class BankAccount {
private int balance;
public synchronized void deposit(int amount){
balance += amount;
}
public synchronized void withdraw(int amount){
balance -= amount;
}
public synchronized int getBalance(){
return balance;
}
}
public class User implements Runnable{
private BankAccount account;
public User(BankAccount account){
this.account = account;
}
@Override
public void run() {
for(int i = 0; i < 1000; i++)
{
account.deposit(10000);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.withdraw(10000);
if(account.getBalance() < 0 || account.getBalance() > 20000)
{
System.out.println(account.getBalance() + "원 ?!?!");
}
}
}
}
public class Test {
public static void main(String[] args) {
BankAccount account = new BankAccount();
Thread t1 = new Thread(new User(account));
Thread t2 = new Thread(new User(account));
t1.start();
t2.start();
}
}
* wait() 와 notify()
생산자와 소비자 문제에 적용하는 것인데.
만약 생산자가 1을 생성하면 소비자가 1을 소비한다 생성자가 2를 생성하면 소비자가 2를 소비한다. 이런식으로 갈때 쓸 수 있다.
ex)
class DataBox{
private String data;
public synchronized String getData(){
if(this.data == null){
try {
wait();
} catch (InterruptedException e) {
// FIXME Auto-generated catch block
e.printStackTrace();
}
}
String returnValue = data;
System.out.println("ConsummerThread 가 읽은 데이터 : " + returnValue);
data = null;
notify();
return returnValue;
}
public synchronized void setData(String data){
if(this.data != null){
try {
wait();
} catch (InterruptedException e) {
// FIXME Auto-generated catch block
e.printStackTrace();
}
}
this.data = data;
System.out.println("ProducerThread가 생성한 데이터 : " + data);
notify();
}
}
class ProducerThread extends Thread{
private DataBox dataBox;
public ProducerThread(DataBox dataBox){
this.dataBox = dataBox;
}
public void run(){
for(int i = 0; i <= 3; i++){
String data = "Data-" + i;
dataBox.setData(data);
}
}
}
class ConsumerThread extends Thread{
private DataBox dataBox;
public ConsumerThread(DataBox dataBox){
this.dataBox = dataBox;
}
public void run(){
for(int i = 0; i <= 3; i++){
String data = dataBox.getData();
}
}
}
wait() 를 하면 잠시 대기!
notify()를 하면 다른 스레드 실행!