15. 스레드
15-1. 스레드의 기본
스레드의 원리
Java : 하나의 코드가, “여러 처리 흐름”을 가질 수 있도록 지원함
- 각각의 처리 흐름 = “스레드”
스레드를 늘리는 행위 = “스레드를 기동시킨다”
- 효율적인 처리가 가능함
스레드 기동시키기
우선, Thread 클래스를 확장한 클래스를 만들어야!
반드시 run() 메소드를 정의해야함
class Car extends Thread
{
public void run()
{
// 다른 스레드가 수행할 작업
}
}
Example
class Car extends Thread
{
private String name;
public Car(String nm)
{
name=nm;
}
public void run()
{
for(int i=0; i<5; i++){
System.out.println(name+"가 동작중")
}
}
}
class Sample
{
public static void main(String[] args)
{
// thread의 서브 클래스 객체 생성
Car car1=new Car("1호차");
// 새로운 thread 기동시키기
car1.start();
for(int i=0;i<5;i++){
System.out.println("main() 메소드 실행 중");
}
}
}
결과
main() 메소드 실행 중
main() 메소드 실행 중
1호차가 동작중
main() 메소드 실행 중
main() 메소드 실행 중
1호차가 동작중
main() 메소드 실행 중
1호차가 동작중
...
- 뭐가 먼저 처리될지는 컴바컴
여러 개의 스레드 기동시키기
class Sample
{
public static void main(String[] args)
{
Car car1=new Car("1호차");
car1.start();
Car car2=new Car("2호차");
car2.start();
for(int i=0;i<5;i++){
System.out.println("Main() 메소드 실행 중")
}
}
}
- 처리흐름이 2개에서 3개로 늘어남!
15-2. 스레드의 상태 변화시키기
스레드 일시정지 ( sleep()
메소드 )
class Car extends Thread
{
private String name;
public Car(String nm)
{
name=nm;
}
public void run()
{
for(int i=0; i<5; i++){
try{
sleep(1000);
System.out.println(name+"가 동작중");
}
catch(InterruptedException e){}
}
}
}
class Sample
{
public static void main(String[] args)
{
Car car1=new Car("1호차");
car1.start();
for(int i=0;i<5;i++){
System.out.println("main() 메소드 실행 중");
}
}
}
결과
- ()안에 지정된 숫자 미리세컨 만큼 스레드 일시 정지
main() 메소드 실행 중
main() 메소드 실행 중
main() 메소드 실행 중
main() 메소드 실행 중
main() 메소드 실행 중
1호차가 동작중
1호차가 동작중
1호차가 동작중
1호차가 동작중
1호차가 동작중
이번엔, main() 메소드가 1초 간격으로 출력되도록!
class Car extends Thread
{
private String name;
public Car(String nm)
{
name=nm;
}
public void run()
{
for(int i=0; i<5; i++){
try{
System.out.println(name+"가 동작중");
}
catch(InterruptedException e){}
}
}
}
class Sample
{
public static void main(String[] args)
{
Car car1=new Car("1호차");
car1.start();
for(int i=0;i<5;i++){
try{
Thread.sleep(1000);
System.out.println("main() 메소드 실행 중");
}
catch(InterruptedException e){}
}
}
}
스레드 종료를 기다리기
join()
메소드 사용하기
- 다른 스레드의 종료를 기다리게끔!
class Car extends Thread
{
private String name;
public Car(String nm)
{
name=nm;
}
public void run()
{
for(int i=0; i<5; i++){
System.out.println(name+"가 동작중")
}
}
}
class Sample
{
public static void main(String[] args)
{
Car car1=new Car("1호차");
car1.start();
try{
car1.join();
}
catch(InterruptedException e){}
System.out.println("main() 메소드 실행 중");
}
}
결과
1호차가 동작중
1호차가 동작중
1호차가 동작중
1호차가 동작중
1호차가 동작중
main() 메소드 실행 중
15-3. 스레드의 생성 방법
스레드를 생성하는 또 다른 방법
Thread 클래스를 상속 받은 클래스가…. 기존에 이미 다른 클래스 상속받았을 경우?
- Runnable 인터페이스를 사용!
- Thread 클래스를 확장하는 것이 아니라, Runnable 인터페이스를 구현!
class Car extends Vehicle implements Runnable
Example
// Runnable 인터페이스 구현
class Car implements Runnable
{
private String name;
public Car(String nm)
{
name=nm;
}
// Run 메소드 정의
public void run()
{
for(int i=0;i<5;i++){
System.out.println(name+"가 동작 중")
}
}
}
class Sample
{
public static void main(String[] args)
{
Car car1=new Car("1호차");
// Thread 클래스의 객체 생성
Thread th1 = new Thread(car1);
// Thread 기동시키기
th1.start();
for(int i=0;i<5;i++){
System.out.println("main() 메소드 실행 중");
}
}
}
15-4. 동기화
스레드 여러개 사용 시 주의점!
동일 필드에, 여러 스레드가 동시에 접근하면 안되는 경우!
public synchronized void add(int a)
{
...
}