5월 30일 쓰레드 보충정리_1
1.동기화의 필요성
멀티쓰레드 환경에서는 여러쓰레드가 같은 자원(메모리)을 공유하기 때문에 어떤 쓰레드가 작업을 마치지 못하고 다른 쓰레드로 넘어갔을때 다른 쓰레드 작업에 영향을 미칠수 있다.
그래서 작업이 끝나지 않은경우에 다른 쓰레드가 그작업을 방해받지 않게 하려면 '동기화'가 필요하다.
2.동기화(synchronization)
한 쓰레드가 진행중인 작업을 다른 쓰레드가 간섭하지 못하게 막는것을 '동기화' 라고 하며,
(1)동기화 하려면 간섭받지 않아야 하는 문장들을 '임계영역'으로 설정
(2)임계영역에는 락(lock)을 얻은 단 하나의 쓰레드만 출입가능(객체1개에 락1개)
3.synchronized 로 임계영역을 설정 가능
(1)메서드 전체를 임계영역으로 지정
public synchronized void 메서드명(){}
임계영역은 한번에 한스레드만 지정할 수 있기때문에 영역을 최소화 한다.
(2)특정한 영역을 임계영역으로 지정
synchronized(객체의 참조변수){}
/*동기화는 2개의 쓰레드를 진행할때, 1번쓰레드와 2번 쓰레드가 같은 영역을 동시에 사용시
*시간차에 의하여 1번쓰레드가 처리를 하는 도중에 2번 쓰레드가 와서 일처리를 해버리므로써 1번 쓰레드는 일처리가 제대로 안되서
*제대로 일처리 못함 이것을 방지하기 위해서 싱크로나이즈(잠금기능)을 설정 하고 열쇠를 1개로 두어 1번 쓰레드가 열쇠를 들고
*임계영역에 가서 작업을 끝나고 열쇠를 올려 놓으면 2번 쓰레드가 그 열쇠를 가지고 가서 작업을 마치게 된다.
*즉, 작업 순서를 정해줌
*
*동기화 방법
*1. 메서드 동기화
* 접근지정자 synchronized 리턴타입 메서드명(매개변수){ ->이거는 키값이 암묵적으로 this이다.
* //동기화가 필요한 코드
* }
*
*1-1.메서드 동기화
*접근지정자 리턴타입 메서드명(){
* synchronized(this){ ->키값이 this이므로 위에 synchronized만 쓴것과 동일한 this키를 공유하므로 같은 블록으로 인식 왜냐면 같은 키값을 공유하므로 , 참고로 this는
* //동기화가 필요한 코드
* }
*}
*
*2. 블록 동기화
* synchronized(임의의 객체){
* //동기화가 필요한코드
* }
*
*/
package study_0520;
class Mydata{
public synchronized void abc() {
for(int i=0; i<3; i++) {
System.out.println(i + "sec");
try {
Thread.sleep(500);
} catch (InterruptedException e) { }
}
}
public synchronized void bcd() {
for(int i=0; i<3; i++) {
System.out.println(i + "초");
try {
Thread.sleep(500);
} catch (InterruptedException e) { }
}
}
public void cde() {
synchronized (this) { // keyobject
// synchronized (new Object()) {
for(int i=0; i<3; i++) {
System.out.println(i + "번째");
try {
Thread.sleep(500);
} catch (InterruptedException e) { }
}
}
}
}
public class SynchronExam {
public static void main(String[] args) {
// 공유객체 (임계 영역)
Mydata myData = new Mydata();
// Thread1
new Thread() {
public void run() {
myData.abc();
}
}.start();
// Thread2
new Thread() {
public void run() {
myData.bcd();
}
}.start();
// Thread3
new Thread() {
public void run() {
myData.cde();
}
}.start();
}
}