일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Daemon()
- include액션태그
- 스레드그룸
- 메모리스트림
- sleep()메소드
- 리눅스세팅
- Linux세팅
- interrupt()
- interrupted()
- 리눅스셋팅
- String char[] 형변환
- Linux셋팅
- InputDialog
- first-of-child
- isinterrupted()
- 상관서브쿼리
- 표현 언어
- char[] String 형변환
- include지시자
- ThreadGroup()
- ObjectInputStream
- MemoryStream
- first-child
- 동기화
- StringWriter
- StringReader
- 아이디중복
- ID중복
- include 지시자
- 상관 서브 쿼리
- Today
- Total
다연이네
[days26] 스레드 - 동기화의 필요성 본문
package days26;
public class Ex09 {
public static void main(String[] args) {
//문제 - 동기화
// 이름을 출력하는 스레드 선언: PrintWorker
// 이름을 출력하는 클래스: PrintMachine (기계는 1대라서 모든 스레드가 공유해서 사용) 공유자원
PrintMachine machine = new PrintMachine(); //머신1대(공유자원)
PrintWorker t1 = new PrintWorker("배다연", machine);
PrintWorker t2 = new PrintWorker("김동준", machine);
PrintWorker t3 = new PrintWorker("남도산", machine);
PrintWorker t4 = new PrintWorker("서달미", machine);
PrintWorker t5 = new PrintWorker("한지평", machine);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
//[[[[[***************김배남서한동다지도달준연산평미***************]]]]]
//=> 동기화(lock)필요
}
}
class PrintWorker extends Thread{
String name = null;
PrintMachine machine = null;
public PrintWorker() {}
public PrintWorker(String name, PrintMachine machine) {
this.name = name;
this.machine = machine;
}
@Override
public void run() {
this.machine.printName(name);
}
}
class PrintMachine{
public void printName(String name) {
//[***홍길동***] 한자씩 찍기로
try {
System.out.print("[");
Thread.sleep(500); // 이거 코딩하고 try~catch로 묶은 다음 코딩 트라이 안에 다 넣기
System.out.print("***");
Thread.sleep(500);
for (int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i));
Thread.sleep(500);
}
System.out.print("***");
Thread.sleep(500);
System.out.print("]");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
출력값
[[[[[***************김배남서한동다지도달준연산평미***************]]]]]
동기화 1) run()에 동기화구문 추가하기 **동기화 객체를 괄호 안에 써준다**
@Override
public void run() {
synchronized (this.machine) {
this.machine.printName(name);
}
}
동기화 2) try~catch구문 감싸기
class PrintMachine{
public void printName(String name) {
synchronized (this) {
try {}
catch (InterruptedException e) {}
}
동기화 3) public과 void 사이에 넣기
class PrintMachine{
public synchronized void printName(String name) {
try {}
catch (InterruptedException e) {}
}
}
1. void interrupt() - 스레드 작업 중지하라고 요청만 한다(실제 중지는 x), 그저 스레드의 interrupted상태를 바꾸는 것
2. static boolean interrupted() - interrupt() 메소드가 호출되었는지 여부 T/F로 돌림
3. boolean isInterrupted() - 현재 interrupted 상태 반환
package days26;
import javax.swing.JOptionPane;
public class Ex10 {
public static void main(String[] args) {
//메인스레드
ThreadEx13_1 th1 = new ThreadEx13_1();
th1.start();
String input = JOptionPane.showInputDialog("아무 값이나 입력하세요 ");
System.out.println("입력하신 값은 "+input+"입니다.");
th1.interrupt(); //t1스레드 중지 요청 - interrupt() 호출하면 interrupted 상태가 true가 된다
System.out.println("isInterrupted() : "+th1.isInterrupted() ); //true 중지 했는지 안했는지 상태값 찍기
}
}
class ThreadEx13_1 extends Thread{
public void run() {
int i = 10;
while (i!=0 && !isInterrupted()) { //값입력해서 확인 누르면 isInterrupted()만나 while 빠져나감
System.out.println(i--);
for (long x=0; x<2500000000L; x++) ; //시간지연 (그냥 아무일도 안하는데 이만큼 시간이 가고 있다는 뜻)
}
System.out.println("카운트 종료");
}
}
InputDialog에 값을 입력하면 interrupt에 의해 while문이 종료되어 카운트가 종료된다.
위의 코딩을 sleep()을 이용하고 싶다면?
while (i!=0 && !isInterrupted()) {
System.out.println(i--);
try {
Thread.sleep(2000);
} catch (Exception e) {
interrupt() ;
}
만약 catch문에 interrupt()가 없다면 숫자를 카운트 끝날때까지 다 찍는다.
main에서 중지요청을 보냈지만 효과가 없는 이유는 무엇일까?
-> 만약 값을 입력하면 main스레스에서 t1.interrupt() 요청이 들어오는데, 마침 sleep상태에 있었다면 (확률99.9%)
(= 대기상황(sleep)에 중지요청을 하면) 예외가 발생한다( e.printStackTrace(); ).
예외를 출력하라는 알고리즘도 없기 때문애 그냥 무시한채 진행한것처럼 보인다.
//결론: catch문 안에 interrupt() 넣어줘야한다
1. suspend() 일시멈춤 - 끄집어내줄때까지는 일 못함
2. resume() 다시시작 - 끄집어내줌
3. stop() 스레드 종료 - 강제종료
=> 모두 폐기될 것(사용금지)
package days26;
public class Ex11 {
public static void main(String[] args) {
RunImpleEx15 r = new RunImpleEx15();
Thread th1 = new Thread(r, "*");
Thread th2 = new Thread(r, "**");
Thread th3 = new Thread(r, "***");
th1.start();
th2.start();
th3.start();
//main스레드가 처리중
try {
Thread.sleep(2000);
th1.suspend(); //실행불가 (메인이 실행시켜야하는데 메인이 쉬고있으니까)
Thread.sleep(2000);
th2.suspend();
Thread.sleep(3000);
th1.resume();
Thread.sleep(3000);
th1.stop();
th2.stop();
Thread.sleep(2000);
th3.stop();
} catch (InterruptedException e) {}
}
}
class RunImpleEx15 implements Runnable{
public void run() {
while(true) {//스레드가 안죽는다(무한루프니까) -> 강제종료 메소드 호출해야함(stop)
System.out.println(Thread.currentThread().getName()); //출력하고
try {
Thread.sleep(1000); //1초 NotRunnable 상태로
} catch (InterruptedException e) { }
}
}
}
위 알고리즘 흐름 알기 ***
'Java' 카테고리의 다른 글
[days27] 동기화 (0) | 2020.10.27 |
---|---|
[days27] 스레드 강제종료 (0) | 2020.10.27 |
[days26] 스레드 예제 (0) | 2020.10.26 |
[days26] 스레드(Thread) (0) | 2020.10.26 |
[days26] 직렬화(Serialization) - ObjectInputStream/ObjectOutputStream (0) | 2020.10.26 |