* 프로세스(process)?
- 현재 CPU에 의해서 처리되는 프로그램.
- 운영체제로부터 메모리를 할당을 받음.
- 자바에서는 하나의 클래스를 의미함.
- 무한반복을 가진 프로세스를 실행할 경우
CPU가 해당 프로세스를 놓지 않기 때문에
다음 프로세스를 실행할 수가 없게 됨.
- 이러한 문제점을 개성하기 위해서
Thread 개념이 도입이 되었음.
* 스레드(Thread)?
- Process를 작은 단위로 쪼개어 놓은 작업 단위.
==> 실제 프로그램이 수행되는 작업의 최소 단위.
- 스레드는 병행 처리를 지원함(멀티태스킹).
- 응용분야 : 게임, 채팅 등등
* [스레드 클래스 작성 방법 - 2가지]
1. Thread라는 클래스 상속(extends)하는 방법.
1) Thread라는 클래스를 상속을 받음.
2) run() 메서드를 재정의. - 스레드 구현.
3-1) 스레드 클래스 객체 생성.
3-2) 참조변수.start() 메서드 호출 ==> run() 메서드 실행.
2. Runnable 인터페이스를 구현(implements) 하는 방법.
1) Runnable 인터페이스를 상속(implements)
2) run() 추상메서드 재정의 ==> 강제성
3) 스레드 클래스(자식클래스) 객체 생성.
4) Thread 라는 클래스 객체 생성.
==> Thread 라는 클래스의 생성자의 인자에
자식클래스의 참조 변수를 기재.
5) Thread 라는 클래스의 참조변수.start() 메서드 호출
* 무명 클래스(anonymous class)를 이용한 스레드 생성의 장점.
- 코드의 집중화로 가독성이 높아진다.
- 별도의 상속 과정이 필요가 없어진다.
* 멀티 스레드와 스레드 이름 지정.
- 멀티 스레드 : 하나의 스레드 클래스를 대상으로
2개 이상의 스레드 객체를 생성하는 기법.
- 스레드 이름 지정 : 멀티스레드에서 생성한 스레드 객체에
이름을 부여하는 과정.
형식) super(name);
- 멀티 스레드는 자신의 이름을 가지고 있음.
- 스레드의 이름이 큰 역할을 하지는 않지만, 디버깅 시
어떤 스레드가 현재 실행되어 작업하는지를 조사(확인)할
목적으로 많이 사용됨.
* synchronized 키워드
* - 스레드 동기화와 관련된 키워드.
* - 멀티스레드에 의해서 공유된 메서드나 클래스를 대상으로
* 임계영역(critical section)을 설정.
* - 임계영역으로 설정된 메서드에서는 가장 먼저 도착한 스레드가
* 완전히 종료될 때까지 나머지 스레드는 대기하는 명령어.
* - 공유되는 자원은 대부분 static 키워드를 가진 객체들을 사용함.
기본예제1) 쓰레드를 사용하지 않는 무한 반복 코딩의 경우 프로그램이 제대로 작동하지 않음
package sist;
class Process1 {
void go() {
int i = 1;
while(true) {
System.out.println("i >>> " + i);
i++;
}
}
}
class Process2 {
void go() {
int j = 1;
while(true) {
System.out.println("j >>> " + j);
j++;
}
}
}
public class Ex01 {
public static void main(String[] args) {
Process1 p1 = new Process1();
Process2 p2 = new Process2();
p1.go(); p2.go();
}
}
예제1) Thread라는 클래스를 이용한 스레드 생성
// Thread라는 클래스 상속(extends)하는 방법
class Thread1 extends Thread { // 1-1)
/*void go() {
int i = 1;
while(true) {
System.out.println("i >>> " + i);
i++;
}
}*/
@Override
public void run() { // 1-2)
int i = 1;
while(true) {
System.out.println("i >>> " + i);
i++;
}
}
}
class Thread2 extends Thread {
/*void go() {
int j = 1;
while(true) {
System.out.println("j >>> " + j);
j++;
}
}*/
@Override
public void run() {
int j = 1;
while(true) {
System.out.println("j >>> " + j);
j++;
}
}
}
public class Ex02 {
public static void main(String[] args) {
// 3-1) 스레드 클래스 객체 생성.
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
// 3-2) 참조변수.start() 메서드 호출 ==> run() 메서드 실행.
t1.start(); t2.start();
}
}
예제2) Runnable 인터페이스를 이용한 스레드 생성
// Runnable 인터페이스로 구현(implements)하는 방법.
package sist;
class Runnable1 implements Runnable {
@Override
public void run() {
int i = 1;
while(true) {
System.out.println("i >>> " + i);
i++;
}
}
}
class Runnable2 implements Runnable {
@Override
public void run() {
int j = 1;
while(true) {
System.out.println("j >>> " + j);
j++;
}
}
}
public class Ex03 {
public static void main(String[] args) {
// 2-3) 스레드 클래스(자식클래스) 객체 생성.
Runnable1 r1 = new Runnable1();
Runnable2 r2 = new Runnable2();
// 2-4) Thread 라는 클래스 객체 생성.
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
// 2-5) Thread 라는 클래스의 참조변수.start() 메서드 호출
t1.start(); t2.start();
}
}
예제3) 무명 클래스를 이용한 스레드 생성
package sist;
public class Ex04 {
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
int i = 1;
while(true) {
System.out.println("i >>> " + i);
i++;
}
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
int j = 1;
while(true) {
System.out.println("j >>> " + j);
j++;
}
}
}).start();
}
}
에제4) 멀티스레드와 스레드 이름 지정
package sist;
/*
* [ATM 클래스 설계서]
* - 입금과 출금의 은행거래가 가능한 ATM 공용 클래스 설계.
* - 계좌잔액 : private int balance;
* - 생성자 : 계좌잔액(balance) 초기화
* - deposit() : 외부 클래스에서 입금하는 메서드.
* 예) balance = balance + money; // 잔액에 입금액을 더함.
* 출력문 : OO,OOO원을 입금하여 OO,OOO원이 남음.
* - withdraw() : 외부 클래스에서 출금하는 메서드.
* 예) balance = balance - money; // 잔액에서 출금액을 차감.
* 출력문 : OO,OOO원을 출금하여 OO,OOO원이 남음.
* (단, balance < money 인 경우 "잔액이 부족합니다." 메세지 출력)
*/
class ATM { // 공용 클래스
private int balance; // 계좌 잔액
public ATM() { }
public ATM(int balance) {
this.balance = balance;
}
// 입금하는 메서드
synchronized void deposit(int money) {
balance = balance + money;
System.out.println
(Thread.currentThread().getName()+"님이 "+
money+"원을 입금하여 "+balance+"원이 남았습니다.");
}
// 출금하는 메서드
synchronized void withdraw(int money) {
if(money > balance) {
System.out.println("잔액이 부족합니다.");
return; // 현재 실행되고 있는 메서드를 종료하는 명령어.
}
balance = balance - money;
System.out.println
(Thread.currentThread().getName()+"님이 "+
money+"원을 출금하여 "+balance+"원이 남았습니다.");
}
}
// 스레드를 구현할 클래스
class User extends Thread {
ATM atm;
public User() { }
public User(ATM atm, String name) {
super(name);
this.atm = atm;
}
@Override
public void run() {
this.atm.deposit(20000); // 입금하는 메서드 호출
this.atm.withdraw(30000); // 출금하는 메서드 호출
}
}
public class ATM_Main {
public static void main(String[] args) {
ATM atm = new ATM(0);
// User 클래스를 대상으로 멀티스레드 객체 생성
User user1 = new User(atm, "홍길동");
User user2 = new User(atm, "이순신");
User user3 = new User(atm, "유관순");
User user4 = new User(atm, "김유신");
User user5 = new User(atm, "김연아");
user1.start(); user2.start();
user3.start(); user4.start(); user5.start();
}
}
'Back > JAVA' 카테고리의 다른 글
JLabel에 ImageIcon을 설정했을 때 텍스트 정렬 (0) | 2021.04.01 |
---|---|
[심화예제] Java Gui와 Event를 이용하여 커피자판기 만들기 (0) | 2021.03.24 |
[심화예제] Java Gui와 Event를 이용하여 회원가입 프로그램 만들기 (0) | 2021.03.23 |
Java GUI(AWT, Swing) - Event (0) | 2021.03.22 |
Java GUI(AWT, Swing) - Layout (0) | 2021.03.22 |