1. 스레드
스레드란???
스레드는 하나의 프로세스 안에서 두 가지 이상의 일을 하도록 한다.
프로세스에서 작업을 수행하는 것이 스레드(Thread)이며 두 가지 이상의 작업을 할려면 두 개 이상의 스레드가 필요하며 두 가지 이상의 작업을 하는 프로세스를 멀티스레드 프로세스라고 한다.
프로세스가 실행되는 방식에는 두 가지가 있으며 시간분할 방식과 선점형 방식이 있다.
2. 스레드의 생성
스레드를 만드는 방법은 Thread 클래스를 상속받는 방법과 Runnable 인터페이스를 구현하는 방법이 있다.
Thread 클래스를 상속받아서 사용하는 것이 간단하지만 인터페이스를 사용하면 다중상속이 가능하기 때문에 주로 Runnable을 사용한다.
📋 코드
package chapter11;
class MyThread extends Thread
{
public void run()
{
for(int i=0;i<100;i++)
{
System.out.println("스레드 진행 중"+i);
}
}
}
class MyThread2 implements Runnable
{
public void run()
{
for(int i=0;i<100;i++)
{
System.out.println("러너블 진행 중"+i);
}
}
}
public class ch11_4 {
public static void main(String[] args) {
MyThread t1 = new MyThread();
Runnable t2 = new MyThread2();
Thread t = new Thread(t2);
t1.start();
t.start();
for (int i=0;i<100;i++)
{
System.out.println("메인 함수 진행 중"+i);
}
}
}
👨🏻💻 결과
메인 함수 진행 중0
메인 함수 진행 중1
메인 함수 진행 중2
메인 함수 진행 중3
스레드 진행 중0
스레드 진행 중1
스레드 진행 중2
러너블 진행 중0
러너블 진행 중1
러너블 진행 중2
러너블 진행 중3
스레드 진행 중3
메인 함수 진행 중4
스레드 진행 중4
스레드 진행 중5
스레드 진행 중6
스레드 진행 중7
스레드 진행 중8
스레드 진행 중9
러너블 진행 중4
러너블 진행 중5
러너블 진행 중6
러너블 진행 중7
메인 함수 진행 중5
메인 함수 진행 중6
러너블 진행 중8
메인 함수 진행 중7
메인 함수 진행 중8
러너블 진행 중9
메인 함수 진행 중9
3. 스레드의 라이프사이클
스레드는 현재 상태에 따라 네 가지로 분류되며 상태가 변화하는 주기를 라이프 사이클이라고 한다.
(1) new
스레드가 키워드 new를 통해서 인스턴스화된 상태이다. Runnable이 될 수 있는 상태이며 대기열에 올라가지 않은 상태이다.
(2) Runnable
start() 메서드가 호출되면 new 상태에서 Runnable 상태가 된다. Runnable 상태가 되면 실행할 수 있는 상태로 대기하게된다. 스케쥴러에 의해 선택이 되면 run() 메서드를 바로 수행한다.
(3) Blocked
실행중인 스레드가 sleep(),join() 메서드를 호출하게 되면 Blocked 상태가 된다. Blocked 상태가 되면 스케쥴러에 의해서 선택받을 수 없다.
(4) Dead
run() 메서드의 실행을 모두 완료하게 되면 스레드는 Dead 상태가 된다. 할당받은 메모리와 정보가 삭제된다.
(1) sleep()
sleep() 메서드는 스레드를 지정된 시간 동안 block 상태로 만든다. 시간은 100분의 1초까지 지정할 수 있으며 지정된 시간이 지나면 다시 runnable 상태로 돌아가게 된다.
다음은 sleep()의 block 효과를 이용해서 카운트다운을 하는 코드이다.
📋 코드
package chapter11;
class Thread1 implements Runnable
{
public void run()
{
for (int i=0;i<=10;i++)
{
System.out.println(i);
if(i!=10)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
System.out.println("종료");
}
}
public class ch11_5 {
public static void main(String[] args) {
Runnable t1 = new Thread1();
Thread t = new Thread(t1);
t.start();
}
}
👨🏻💻 결과
0
1
2
3
4
5
6
7
8
9
10
종료
(2) join()
join() 메서드는 특정한 스레드가 작업을 먼저 수행할 때 사용하며 마치 새치기와 같다.
싱글스레드와 같은 기능을 구현한다.
📋 코드
package chapter11;
class MyThread8 implements Runnable
{
public void run()
{
for(int i = 0;i<10;i++)
{
System.out.println("t1 :" +i);
}
System.out.println("t1 완료");
}
}
class MyThread9 implements Runnable
{
public void run()
{
for(int i = 0;i<10;i++)
{
System.out.println("t2 :" +i);
}
System.out.println("t2 완료");
}
}
public class ch11_6 {
public static void main(String[] args) {
MyThread8 s1 = new MyThread8();
MyThread9 s2 = new MyThread9();
Thread t1 = new Thread(s1);
Thread t2 = new Thread(s2);
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t2.start();
try {
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i=0;i<10;i++)
{
System.out.println("메인스레드"+i);
}
System.out.println("메인스레드 완료");
}
}
👨🏻💻 결과
t1 :0
t1 :1
t1 :2
t1 :3
t1 :4
t1 :5
t1 :6
t1 :7
t1 :8
t1 :9
t1 완료
t2 :0
t2 :1
t2 :2
t2 :3
t2 :4
t2 :5
t2 :6
t2 :7
t2 :8
t2 :9
t2 완료
메인스레드0
메인스레드1
메인스레드2
메인스레드3
메인스레드4
메인스레드5
메인스레드6
메인스레드7
메인스레드8
메인스레드9
메인스레드 완료
4. 스레드의 동기화
스레드의 동기화란 멀티 스레드로 작업을 할 때, 스레드 간의 직업이 간섭되지 않도록 하는 것이다.
📋 코드
package chapter11;
class MyThreadB implements Runnable
{
Ticketing ticket = new Ticketing();
public void run()
{
ticket.ticketing();
}
}
class Ticketing
{
int ticketnumber = 2;
public synchronized void ticketing()
{
if(ticketnumber>0)
{
System.out.println(Thread.currentThread().getName()+"가 티켓팅 성공");
ticketnumber = ticketnumber-1;
}
else
{
System.out.println(Thread.currentThread().getName()+"가 티켓팅 실패");
}
System.out.println(Thread.currentThread().getName()+"가 티켓팅시도 후 티켓수 : "+ ticketnumber);
}
}
public class ch11_7 {
public static void main(String[] args) {
MyThreadB s1 = new MyThreadB();
Thread t1 = new Thread(s1,"A");
Thread t2 = new Thread(s1,"B");
Thread t3 = new Thread(s1,"C");
t1.start();
t2.start();
t3.start();
}
}
👨🏻💻 결과
A가 티켓팅 성공
A가 티켓팅시도 후 티켓수 : 1
C가 티켓팅 성공
C가 티켓팅시도 후 티켓수 : 0
B가 티켓팅 실패
B가 티켓팅시도 후 티켓수 : 0
5.wait()과 notify()
스레드를 대기시키는 wait() 메서드와 대기 중인 스레드를 깨우는 notify() 메서드를 통해 스레드를 제어할 수 있다.
package chapter11;
class Account
{
int money = 0;
public int showMoney()
{
return money;
}
public synchronized void setMoney()
{
try
{
Thread.sleep(10);
}
catch (InterruptedException ie)
{
System.out.println(ie.toString());
}
this.money+=2000;
System.out.println("어머니가 용돈을 입금했습니다. 현재 잔액"+this.showMoney());
this.notify();
}
public synchronized void getMoney()
{
while(money<=0)
{
try {
System.out.println("통장 잔고가 없어서 아들 대기 중");
this.wait();
}
catch (InterruptedException ie) {
System.out.println(ie.toString());
}
}
this.money-=2000;
System.out.println("아들이 용돈을 출금했습니다. 현재 잔액"+this.showMoney());
}
}
class Son extends Thread
{
private Account account;
Son(Account account)
{
this.account = account;
}
public void run()
{
for(int i=0;i<10;i++)
{
account.getMoney();
}
}
}
class Mom extends Thread
{
private Account account;
Mom(Account account)
{
this.account = account;
}
public void run()
{
for(int i=0;i<10;i++)
{
account.setMoney();
}
}
}
public class ch11_8
{
public static void main(String[] args)
{
Account account = new Account();
Son son = new Son(account);
Mom mom = new Mom(account);
son.start();
mom.start();
}
}
👨🏻💻 결과
통장 잔고가 없어서 아들 대기 중
어머니가 용돈을 입금했습니다. 현재 잔액2000
어머니가 용돈을 입금했습니다. 현재 잔액4000
어머니가 용돈을 입금했습니다. 현재 잔액6000
어머니가 용돈을 입금했습니다. 현재 잔액8000
어머니가 용돈을 입금했습니다. 현재 잔액10000
어머니가 용돈을 입금했습니다. 현재 잔액12000
어머니가 용돈을 입금했습니다. 현재 잔액14000
어머니가 용돈을 입금했습니다. 현재 잔액16000
어머니가 용돈을 입금했습니다. 현재 잔액18000
어머니가 용돈을 입금했습니다. 현재 잔액20000
아들이 용돈을 출금했습니다. 현재 잔액18000
아들이 용돈을 출금했습니다. 현재 잔액16000
아들이 용돈을 출금했습니다. 현재 잔액14000
아들이 용돈을 출금했습니다. 현재 잔액12000
아들이 용돈을 출금했습니다. 현재 잔액10000
아들이 용돈을 출금했습니다. 현재 잔액8000
아들이 용돈을 출금했습니다. 현재 잔액6000
아들이 용돈을 출금했습니다. 현재 잔액4000
아들이 용돈을 출금했습니다. 현재 잔액2000
아들이 용돈을 출금했습니다. 현재 잔액0
'Java > 단계별 과정' 카테고리의 다른 글
[JAVA]컬렉션 프레임워크(Collection FrameWork) (0) | 2023.05.09 |
---|---|
[JAVA]기본 API 클래스 (0) | 2023.05.03 |
[JAVA] 예외 처리(Exception Handing) (0) | 2023.05.03 |
[JAVA]추상 메서드와 추상 클래스 (0) | 2023.05.02 |
[JAVA] 상속과 다형성 (0) | 2023.05.01 |