오늘은 스레드의 개념과 자바에서의 스레드 사용법을 알아봅시다!
스레드는 프로세스 내에서 실행되는 흐름의 단위를 말합니다. 일반적으로 한 프로그램은 하나의 스레드를 가지고 있지만, 프로그램 환경에 따라 둘 이상의 스레드를 동시에 실행할 수 있습니다.
자바에서의 스레드는 main()안의 실행문들이 하나의 스레드입니다.
main()이외의 스레드를 만들려면 Thread 클래스를 상속하거나 Runnable 인터페이스를 구현해야합니다.
두 방법을 모두 알아봅시다!
1. Thread 클래스 상속
DownloadThread.java
package test.mypac;
/*
* 새로운 스레드 만드는 방법
*
* 1. Thread 클래스를 상속 받은 클래스를 정의한다.
* 2. run() 메소드를 오버라이드한다.
* 3. run() 메소드 안에서 새로운 스레드에서 해야할 작업을 코딩한다.
* 4. 만든 클래스로 객체를 생성하고 해당 객체의 start() 메소드를 호출하면 새로운 스레드가 시작된다.
*/
public class DownloadThread extends Thread{
@Override
public void run() {
//완료하는데 10초가 걸리는 작업을 한다고 가정하자
try {
Thread.sleep(10000);
System.out.println("다운로드가 완료 되었습니다.");
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
main.java
package test.main;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import test.mypac.DownloadThread;
public class Frame02 extends JFrame implements ActionListener{
//생성자
public Frame02() {
setTitle("Frame02");
setBounds(100, 100, 800, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JTextField inputText=new JTextField(10);
add(inputText);
JButton btn1=new JButton("눌러보셈");
add(btn1);
btn1.addActionListener(this);
setVisible(true);
}
public static void main(String[] args) {
new Frame02();
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("버튼을 눌렀네요!");
//새로운 스레드에서 다운로드 작업을 시킨다.
new DownloadThread().start();
System.out.println("actionPerformed() 메소드가 종료 됩니다.");
}
}
Thread를 상속받은 스레드 클래스를 만들어 준 후 main에서 .start()를 사용하여 실행시켜줍니다.
스레드 클래스를 사용하지않고 main() 내에서 바로 사용할 수도 있습니다.
package test.main;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import test.mypac.DownloadThread;
public class Frame05 extends JFrame implements ActionListener{
//생성자
public Frame05() {
setTitle("Frame05");
setBounds(100, 100, 800, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JTextField inputText=new JTextField(10);
add(inputText);
JButton btn1=new JButton("눌러보셈");
add(btn1);
btn1.addActionListener(this);
setVisible(true);
}
public static void main(String[] args) {
new Frame05();
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("버튼을 눌렀네요!");
//익명의 내부 클래스를 이용해서 객체 생성후 새로운 작업단위를 시작한다.
new Thread() {
@Override
public void run() {
//완료하는데 10초가 걸리는 작업을 한다고 가정하자
try {
Thread.sleep(10000);
System.out.println("다운로드가 완료 되었습니다");
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}.start();
System.out.println("actionPerformed() 메소드가 종료 됩니다.");
}
}
new Thread를 사용하여 익명의 내부 클래스를 이용해서 객체 생성을 하였습니다.
2. Runnable 인터페이스 사용
CountRunnable.java
package test.mypac;
/*
* 새로운 스레드 만드는 방법2
*
* 1. Runnable 인터페이스를 구현한 클래스를 정의한다.
* 2. run() 메소드를 강제 오버라이드 한다.
* 3. Thread 클래스로 객체를 생성하면서 해당클래스로 만든 객체를 생성자의 인자로 전달한다.
* 4. Thread 클래스로 만든 객체의 start() 메소드를 호출해서 스레드를 시작 시킨다.
*/
public class CountRunnable implements Runnable{
@Override
public void run() {
int count=0;
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++; //카운트를 증가 시킨다.
System.out.println("현재 카운트:"+count);
if(count==10) break;// 카운트가 10이 되면 반복문 탈출 => run()메소드종료 => 스레드 종료를 의미
}
}
}
Runnable 인터페이스를 사용한 방법입니다. run을 오버라이드해주었습니다.
package test.main;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import test.mypac.CountRunnable;
import test.mypac.DownloadThread;
public class Frame06 extends JFrame implements ActionListener{
//생성자
public Frame06() {
setTitle("Frame06");
setBounds(100, 100, 800, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JTextField inputText=new JTextField(10);
add(inputText);
JButton btn1=new JButton("눌러보셈");
add(btn1);
btn1.addActionListener(this);
setVisible(true);
}
public static void main(String[] args) {
new Frame06();
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("버튼을 눌렀네요!");
Thread t=new Thread(new CountRunnable());
t.start();
System.out.println("actionPerformed() 메소드가 종료 됩니다.");
}
}
main 에서 start를 시켜주었습니다.
Thread와 마찬가지로 Runnable 클래스를 따로 만들지 않고 바로 main에서 사용할 수 도 있습니다.
package test.main;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import test.mypac.CountRunnable;
import test.mypac.DownloadThread;
public class Frame08 extends JFrame implements ActionListener{
//생성자
public Frame08() {
setTitle("Frame06");
setBounds(100, 100, 800, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JTextField inputText=new JTextField(10);
add(inputText);
JButton btn1=new JButton("눌러보셈");
add(btn1);
btn1.addActionListener(this);
setVisible(true);
}
public static void main(String[] args) {
new Frame08();
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("버튼을 눌렀네요!");
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
int count=0;
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++; //카운트를 증가 시킨다.
System.out.println("현재 카운트:"+count);
if(count==10) break;// 카운트가 10이 되면 반복문 탈출 => run()메소드종료 => 스레드 종료를 의미
}
}
}).start();
System.out.println("actionPerformed() 메소드가 종료 됩니다.");
}
}
람다 함수를 사용해서도 만들 수 있습니다.
package test.main;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import test.mypac.CountRunnable;
import test.mypac.DownloadThread;
public class Frame09 extends JFrame implements ActionListener{
//생성자
public Frame09() {
setTitle("Frame06");
setBounds(100, 100, 800, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JTextField inputText=new JTextField(10);
add(inputText);
JButton btn1=new JButton("눌러보셈");
add(btn1);
btn1.addActionListener(this);
setVisible(true);
}
public static void main(String[] args) {
new Frame09();
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("버튼을 눌렀네요!");
new Thread(()->{
int count=0;
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e2) {
e2.printStackTrace();
}
count++; //카운트를 증가 시킨다.
System.out.println("현재 카운트:"+count);
if(count==10) break;// 카운트가 10이 되면 반복문 탈출 => run()메소드종료 => 스레드 종료를 의미
}
}).start();
System.out.println("actionPerformed() 메소드가 종료 됩니다.");
}
}
'Languages > JAVA' 카테고리의 다른 글
[JAVA] String VS StringBuilder VS StringBuffer (2) | 2022.07.20 |
---|---|
[JAVA] JFrame 사용해보기 #2 - DB 연동 (DTO, DAO) (0) | 2021.11.17 |
[JAVA] JFrame 사용해보기 #1 - 예제로 다양한 기능 알아보기 (0) | 2021.11.16 |
[JAVA] 상속 알아보기 #2 - this, super (0) | 2021.11.15 |
[JAVA] 상속 알아보기 #1 - 기본 개념, 오버라이딩, 생성자 호출, 다형성 (0) | 2021.11.15 |