동시성 : 멀티 작업을 위해 하나의 코어에서 멀티 스레드가 번갈아가며 실행하는 성질
병렬성 : 멀티 작업을 위해 멀티 코어에서 개별 스레드를 동시에 실행하는 성질
public void method() {
//여러 스레드가 실행 가능한 영역
...
synchronized(공유객체) { // 공유 객체가 객체 자신이면 this를 넣을 수 있음
임계 영역 //단 하나의 스레드만 실행
}
//여러 스레드가 실행 가능한 영역
}
ex.
Thread 생성자 자체에 이름을 매개변수로 받는 생성자가 있음
public class Worker extends Thread {
Work work; // 일
int workLoad; // 얼마나 일해라 50
// thread에 이름 지정
public Worker(Work work, int workLoad, String name) {
super(name); // new Thread(name);
this.work = work;
this.workLoad = workLoad;
}
// Thread로 수행되는 메소드
public void run() {
for (int i=1; i<=workLoad; i++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 동기화 (객체) {}
synchronized (work) { // 공유 객체가 자신이면 this 넣음
// 전체 스레드가 동시에 접근하지 못하고 한번에 하나만 접근하도록 함
work.addCnt(); //++ ++ 50번
}
// 현재 스레드의 이름 출력
System.out.println(Thread.currentThread().getName() + " -> " + work.toString());
}
}
}
public class ThreadWorkTest1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Work work = new Work();
Worker worker1 = new Worker(work, 50, "1번 일꾼");
Worker worker2 = new Worker(work, 50, "2번 일꾼");
// 만약 Thread 상속 안받고 그냥 run이라는 메소드를 실행했으면
// worker1의 업무가 끝날때까지 기다려야했지만, 스레드를 사용하면
// 일을 병렬적으로 시킬 수 있음
worker1.start();
worker2.start();
// 둘다 일하면서 숫자 ++ 하는데 최종적으로 증가하는 수는 50 + 50이 아니야..
// 객체에 동시에 접근하면서 충돌 발생..
}
}
class Work {
int workCnt; // 일거리 갯수
public Work() {
workCnt = 0;
}
public void addCnt() {
workCnt++;
}
public String toString() {
return String.valueOf(workCnt);
}
}
: 주어진 시간동안 스레드를 일시 정지 상태로 만들고 주어진 시간이 지나면 자동적으로 실행 대기 상태
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
// interrupt() 메소드가 호출되면 실행
}
: join 메소드를 호출한 스레드는 일시 정지 상태가 된다. 실행대기 상태로 가려면 join 메소드를 멤버로 가지는 스레드가 종료되거나 매개값으로 주어진 시간이 지나야함
public class JoinExample {
public static void main(String[] args) {
SumThread sumThread = new SumThread();
sumThread.start();
try {
// sumThread가 종료할 때까지 메인 스레드를 일시 정지시킴
sumThread.join();
} catch(InterruptedException e) {
}
System.out.println("1~100 합: " + sumThread.getSum());
}
}
: 동기화 블록 내에서 스레드를 일시 정지 상태로 만든다. 매개값으로 주어진 시간이 지나면 자동적으로 실행 대기 상태가 되고, 시간이 주어지지 않으면 notify, notifyAll에 의해 실행 대기 상태로 갈 수 있음
: 동기화 블록 내에서 wait 메소드에 의해 일시 정지 상태에 있는 스레드를 실행 대기 상태로 만든다
: notify는 한개, notifyAll은 여러개
: Object 클래스에 선언된 메소드여서 모든 공유 객체에서 호출 가능하지만, 동기화 메소드 or 동기화 블록 내에서만 사용 가능
class WorkObject {
public synchronized void methodA() {
System.out.println("ThreadA의 methodA() 작업 실행");
// 일시 정지 상태에 있는 ThreadB를 실행 대기 상태로 만듦
notify();
try {
// ThreadA를 일시 정지 상태로 만듦
wait();
} catch(InterruptedException e) {
}
}
public synchronized void methodB() {
System.out.println("ThreadB의 methodB() 작업 실행");
// 일시 정지 상태에 있는 ThreadA를 실행 대기 상태로 만듦
notify();
try {
// ThreadB를 일시 정지 상태로 만듦
wait();
} catch(InterruptedException e) {
}
}
}