
프로세스 : 스레드 = 공장 : 일꾼동기화에 주의해야 한다.교착상태가 발생하지 않도록 주의해야 한다.class MyThread extends Thread {
public void run() {
}
}
Mythread t = new Myth();
t.start();
class MyThread implements Runnable{
public void run() {
}
}
Runnable r = new MyThread();
Thread t = new Thread(r); //Thread(Runnable r)
t.start();
Thread t = new Thread(new MyThread());
실행 가능한 상태가 되는거지 바로 실행되는게 아니다. 실행하는건 OS 스케쥴러가 결정한다.ThreadEx1_1 t1 = new ThreadEx1_1();
ThreadEx1_1 t2 = new ThreadEx1_1();
t1.start();
t2.start();
-main 스레드 : main 메서드의 코드를 수행하는 스레드
사용자 스레드와 데몬 스레드(보조 스레드)가 있다보조스레드는 보조 스레드라서 실행 중이더라도 프로그램 종료가 된다.Thread MyThread t1 = new Thread();
t1.start();
for (int i=0; i<300; i++) {
System.out.println("-");
}
메인스레드와 t1 스레드가 함께 섞여서 출력됨.
main(String args[]) 이게 메인 스레드라는 것!
class ThreadTest {
public static void main(String args[]) {
for(int i=0; i<300, i++) {
System.out.println("_");
}
for(int i=0; i<300, i++) {
System.out.println("|");
}
}
}


싱글 스레드로 돌릴 때는 두 작업이 절대 겹치지 않음
class ThreadTest{
public static void main(String args[]) {
MyThread t1 = new MyThread();
MyThread2 t2 = new MyThread2();
t1.start();
t2.start();
}
}
class MyThread exteds Thread() {
public void run() {
for(int i=0; i<300;i++) {
System.out.println("-");
}
}
}
class MyThread2 exteds Thread() {
public void run() {
for(int i=0; i<300;i++) {
System.out.println("|");
}
}
}
멀티 스레드일 경우임. 이 때는 두 작업이 겹침. 어떤 작업이 먼저 시작할지는 모름
class ThreadEx{
String input = JOptionPane.showInputdialog("아무 값이나 입력하세요.");
System.out.println("입력하신 값은" + input + "입니다.");
for (int i=0;; i>0; i--) {
System.out.println(i);
try(Thread.sleep(1000)
}
}
}

class ThreadEx1{
public static void main(String args[]) {
THreadEx1 th1 = new ThreadEx1();
th1.start();
String input = JOptionPane.showInputdialog("아무 값이나 입력하세요.");
System.out.println("입력하신 값은" + input + "입니다.");
}
}
class ThreadEx2 extends Thread{
public void run() {
for(int i=0; i>0; i--) {
System.out.println(i);
try{sleep(1000);} catch(Exception e) {}
}
}
}
void setPriority(int newPriority) : 스레드의 우선순위를 지정한 값으로 변경한다int getPriority() : 스레드의 우선순위를 반환한다.public static final int MAX_PRIORITY = 10;
public static final int MIN_PRIORUTY = 1;
public static final int NORM_PRIORITY = 5;
우선순위를 지정하지 않으면 5로 지정됨.

이론적으로는 우선순위가 높은 스레드가 더 많은 시간을 할당받음....이지만, 실제는 다름. 스레드의 우선순위는 단지 희망사항에 불과함.

깊이 있게 아려고 하지 마시고 스레드가 그룹으로 관리된다는 것 정도 알아두시기 바랍니다.
public void run() {
while(true) { //무한루프
try {
Thread.sleep(3*1000)'
} catch(InterruptedException e) {}
if(autoSave) { //특정 조건일 때 실행
autoSave();
}
}
}
boolean isDaemon() - 스레드가 데몬스레디인지확인한다. 데몬스레드면 true 반환
void setDaemon(boolean on) - 스레드를 데몬 스레드로 또는 사용자 스레드로 변경. 매게변수 on을 true로 지정하면 데몬 스레드가 된다.
반드시 start()를 호출하기 전에 실행되어야 한다. 그렇지 않으면 illegalThreadStateEception이 발생한다.public class Excercise13_7 implements Runnable {
static boolean autoSave = false;
public static void main(String[] args) {
Thread t = new Thread(new Excercise13_7()); //Thread(Runnable r)
//지금 이 클레스를 스레드의 생성자에 전달한다.
t.setDaemon(true);
t.start();
for (int i=1; i<=10; i++) {
try {
Thread.sleep(1000);
} catch(InterruptedException e) {}
System.out.println(i);
if (i==5) autoSave =true;
}
System.out.println("프로그램을 종료합니다.");
}
public void run() { //데몬스레드가 됨.
while(true) {
try {
Thread.sleep(3*1000);
} catch (InterruptedException e) {}
if(autoSave) autoSave();
}
}
public void autoSave() {
System.out.println("작업파일일 자동 저장되었습니다.");
}
}
결과▼



sleep() yied()가 있다. 특징 : 자기 자신한테만 동작한다.static void sleep(long millis)
static void sleep(long milles, int nanao) //잘 안씀. 몰라도 됨.
try {
Thread.sleep(1,500000);
} catch(InterruptedException이 e) {} //안에 아무것도 안 써도 됨
}
항상 이렇게 예외처리를 해줘야하는데 불편하잖아요.
그러니까 메서드를 따로 만들어요. ex)delay sleep마세더를 다른 메서드 안에 넣은거에요.
void delay(long millis) {
try{
Thread.sleep(millis);
} catch(InterruptedException이 e) {}
}





public class Ex13_9 {
public static void main(String[] args) {
ThreadEx9_1 th1 = new ThreadEx9_1();
th1.start();
String input = JOptionPane.showInputDialog("아무 값이나 입력하세요.");
System.out.println("입력하신 값은" + input + "입니다");
th1.interrupt();
System.out.println("isinterrupted():" + th1.isInterrupted());
System.out.println("interrupted():"+ th1.interrupted()); //main 스레드가 interrupt 됐는지😶
}
}
class ThreadEx9_1 extends Thread{
public void run() {
int i = 10;
while(i!=0 && !isInterrupted()) {
System.out.println(i--);
for (long x =0; x <2500000000L; x++);
}
System.out.println("카운트가 종료되었습니다.");
}
}


이 예제를 보면 알 수 있는게, interrupt가 스레드를 멈추게 하지 않음. 당시 interrupt 변수 상태를 바꿔서 그걸 이용해서 메서드를 종료하게 내가 메서드를 설계하는거임(interrupt 변수가 false가 되면 print그만해라).
흠...그럼 interrupt가 굳이 왜 있는지는 모르겠음...딱히 일시정지 상태도 아니지않나....흠....실무에서 써봐야 존재 이유가 이해가 가려나...

th1.join() //`main스레드`가 `th1스레드`가 끝날 때까지 기다린다.
동기화 필요임계 영역으로 설정public synchronized void calcSum(){
}
그런데 임계 영역이 적을 수록 효율적이다. 최소화하는게 좋다.
2. 특정한 영역을 임계 영역으로 지정
synchronized(객체의 참조변수) {
}
public void withdraw(int money) {
synchronized(this) {
if(balance >=money) {
try{
Thread.sleep(1000);
} catch (exception e) {}
balance -= money;
}
}
}

wait과 notify할 사람이 불분명. 요리사? 손님?
음식이 없을 때 손님을 깨우려면?
Lock&condition
public class ThreadEx21 {
public static void main(String[] args) {
Runnable r= new RunnableEx21(); //RunnableEx의 객체를 1개 만듦
Thread th1 = new Thread(r); //그 객체를 th1 스레드로 공유함
Thread th2 = new Thread(r); //그 객체를 th2 스레드로 공유함
th1.start();
th2.start();
}
}
runnable 클래스의 객체를 하나 만들고
그 하나의 객체로 스레드를 여러개 만드는구나....
객체 여러개 만들고 각 개체당 스레드를 만들지 않는구나...
class Account {
private int balance = 1000;
public int getBalance() {
return balance;
}
public void withdraw(int money) {
if(balance>=money) {
try {Thread.sleep(1000);
} catch(InterruptedException e) { }
balance -= money;
}
}
}
withdraw 앞에 synchronized를 붙이면 동기화 된다.
단, private int balance로 해야 의미가 있다.
class RunnableEx21 implements Runnable {
Account acc = new Account();
public void run() {
while(acc.getBalance() > 0) {
// 100, 200, 300 중 임의의 값을 선택해서 출금(withdraw)
int money = (int) (Math.random() * 3 +1 ) *100;
acc.withdraw(money);
System.out.println("balance:" + acc.getBalance());
}
}
}