package kr.or.didt.basic;
public class ThreadTest01 {
public static void main(String[] args) {
//메인 스레드 라고 부름(여기에서 처리되는 것은 싱글 스레드)
//싱글 스레드 프로그램
for (int i = 1; i < 200; i++) {
System.out.print("*");
}
System.out.println();
System.out.println();
for (int j = 1; j <= 200; j++) {
System.out.print("$");
}
}
}
package kr.or.didt.basic;
public class ThreadTest2 {
public static void main(String[] args) {
// 멀티 쓰레드 프로그램
//Thread를 사용하는 방법
//방법1
// ==> Thread클래스를 상속한 class를 작성한 후
// 이 class의 인스턴스(객체)를 생성한 후
// 이 인스턴스의 start()메서드를 호출해서 실행한다
MyThread1 th1 = new MyThread1(); //인스턴스 생성하기
th1.start(); //쓰레드 실행하기
//방법2
// ==> - Runnable 인터페이스를 구현한 class를 작성한다.
// - 이 class의 인스턴스를 생성한다.
// - Thread클래스의 인스턴스를 생성할 때 생성자의 인수값으로
// 이 class의 인스턴스를 넣어준다.
// - Thread클래스의 인스턴스의 start()메서드를 호출해서 실행한다.
// MyRunner1 r = new MyRunner1();
Thread th2 = new Thread(new MyRunner1()); //문자 하나씩출력되고 빨간색이 사라지면 끝난 것
th2.start();
//start로 하지 않고 run으로 구현하면 싱글 스레드로 사용됨(멀티 스레드 환경이 아니게 됨)
//start는 즉 스레드 환경을 만들어주고 run을 자동으로 호출해 준다.
//방법3 ==> 익명구현체를 이용하는 방법
//익명구현체란? 이름없이 구현할 수 있는것
Thread th3 = new Thread(new Runnable() {
//new MyRunner1()을 쓰지 않고 직접 구현해서 넣기
@Override
public void run() {
for (int i = 1; i < 200; i++) {
System.out.print("@");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
});
th3.start();
System.out.println("main() 메서드 끝...");
//어느시점에 끝이 실행될까..?
//모든 쓰레드가 다끝날때!!
}
}
// 방법1 - Thread클래스 상속하기
class MyThread1 extends Thread{
@Override
public void run() {
//이 run()메서드 안에는 쓰레드에서 처리할 내용을 기술한다.
for (int i = 1; i < 200; i++) {
System.out.print("*");
try {
//Thread.sleep(시간); ==> 주어진 '시간'동안 잠시 멈춘다.
// '시간'은 밀리세컨드 단위를 사용한다.
// 즉, 1000은 1초를 의미한다.
Thread.sleep(1000);
} catch (Exception e) {
}
}
}
}
// 방법2 - Runnable인터페이스 구현하기
class MyRunner1 implements Runnable{//상속이 이미 있을때 이것을 씀
@Override
public void run() {
for (int i = 1; i < 200; i++) {
System.out.print("$");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}
package kr.or.didt.basic;
public class ThreadTest03 {
public static void main(String[] args) {
// 쓰레드가 수행되는 시간 체크하기
Thread th = new Thread(new MyRunner2());
//쓰레드를 상속하느 방법과 러너블을 실행하는 방법은 두가지임
// 1970년 1월 1일 0시 0분 0초(표준시간)로 부터 경과한 시간을
// 밀리세컨드 단위(1/1000초)로 반환한다.
long startTime = System.currentTimeMillis();
th.start();
try {
th.join(); //현재 실행중인 쓰레드에서 대상이 되는 쓰레드
//쓰레드(여기서는 변수th)가 종료될 때까지 기다린다.
} catch (InterruptedException e) {
// TODO: handle exception
}
long endTime = System.currentTimeMillis();//end는 실제 스레드가 끝날때를 의미
System.out.println("경과 시간: " + (endTime - startTime));
//end-start=경과시간
//1000분의 1초가 경과시간
}
}
class MyRunner2 implements Runnable{
@Override
public void run() {
long sum = 0L;
for(long i=1; i<=1000_000_000L; i++){//숫자의 _는 문자취급 안함
sum += i;
}
System.out.println("합계 : " + sum);
}
}

package kr.or.didt.basic;
/*
* 1 ~ 20억까지의 합계를 구하는 프로그램 작성하기
* - 이 작업을 하나의 쓰레드가 단독으로 처리하는 경우와
* 여러개의 쓰레드가 협력해서 처리할 때의 경과시간을 비교해 본다.
*
*/
public class TreadTest04 {
public static void main(String[] args) {
//단독으로 처리할 쓰레드 생성
SumThread sm = new SumThread(1L, 2_000_000_000L);
//협력해서 처리할 쓰레드 생성 (4개의 쓰레드 객체 생성)
SumThread[] smArr = new SumThread[]{
new SumThread( 1L, 500_000_000L),
new SumThread( 500_000_000L, 1_000_000_000L),
new SumThread(1_000_000_000L, 1_500_000_000L),
new SumThread(1_500_000_000L, 2_000_000_000L),
};
// 단독으로 처리하기
long startTime = System.currentTimeMillis();
sm.start();
try {
sm.join();
} catch (InterruptedException e) {
// TODO: handle exception
}
long endTime = System.currentTimeMillis();
System.out.println("단독으로 처리할 때의 경과 시간 : "
+ (endTime - startTime));
System.out.println();
System.out.println();
// 여러 쓰레드가 협력해서 처리하는 경우
startTime = System.currentTimeMillis();
for(SumThread s : smArr){
s.start();
}
//일부러 다른 방법
for (int i = 0; i < smArr.length; i++) {
try {
smArr[i].join();
} catch (InterruptedException e) {
// TODO: handle exception
}
}
endTime = System.currentTimeMillis();
System.out.println("협력해서 처리한 경과 시간 : "
+ (endTime - startTime) );
}
}
class SumThread extends Thread{
//합계를 구할 영역의 시작값과 종료값이 저장될 변수 선언
private long min, max;
public SumThread(long min, long max) {//생성자
this.min = min;
this.max = max;
}
@Override
public void run() {
long sum = 0L;
for(long i = min; i <= max; i++){
sum += i;
}
System.out.println("합계 : "+sum);
}
}
package kr.or.didt.basic;
public class ThreadTest05 {
public static void main(String[] args) {
Thread th1 = new UpperThread();
Thread th2 = new LowerThread();
//우선 순위 변경하기 - start()메서드 호출 전에 설정한다.
th1.setPriority(6);
th1.setPriority(8);
System.out.println("th1의 우선순위 : "+ th1.getPriority());
System.out.println("th2의 우선순위 : "+ th2.getPriority());
th1.start();
th2.start();
}
}
//대문자를 출력하는 쓰레드
class UpperThread extends Thread{
@Override
public void run() {
for (char c = 'A'; c <= 'Z'; c++) {
System.out.println(c);
//아무작업도 안하는 반복문(시간 때우기용)
for (long i = 1L; i < 100_000_000L; i++) { }
}
}
}
//소문자를 출력하는 메서드
class LowerThread extends Thread{
@Override
public void run() {
for (char c = 'a'; c <= 'z'; c++) {
System.out.println(c);
//아무작업도 안하는 반복문(시간 때우기용)
for (long i = 1L; i < 100_000_000L; i++){ }
}
}
}
package kr.or.didt.basic;
//데몬 쓰레드 연습 ==> 자동 저장하는 쓰레드
public class ThreadTest06 {
public static void main(String[] args) {
AutoSaveThread autoSave = new AutoSaveThread();
//데몬 쓰레드로 설정하기 ==> 반드시 start() 메서드 호출 전에 설정한다.
autoSave.setDaemon(true);
//실행하지 않으면 작업 내용 저장이 3초에 한번씩 계속 반복된다.
autoSave.start();
try {
for (int i = 0; i <20; i++) {
System.out.println(i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println("main 쓰레드 작업 끝...");
}
}
// 자동 저장하는 쓰레드 작성 (3초에 한번씩 자동 저장하기)
class AutoSaveThread extends Thread{
// 작업 내용을 저장하는 메서드
public void save(){
System.out.println("작업 내용을 저장합니다...");
}
@Override
public void run() {
while(true){
try {
Thread.sleep(3000);
} catch (Exception e) {
}
save();
}
}
}
package kr.or.didt.basic;
import javax.swing.JOptionPane;
public class ThreadTest07 {
public static void main(String[] args) {
//사용자로부터 데이터 입력 받기
String str = JOptionPane.showInputDialog("아무거나 입력하세요");
System.out.println("입력값 : " + str);
//입력하면 입력한 값 출력, 취소하면 null값 출력
//--------------------------------------------
for (int i = 10; i >= 1; i--) {
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO: handle exception
}
}
}
}
package kr.or.didt.basic;
import javax.swing.JOptionPane;
public class ThreadTest08 {
public static void main(String[] args) {
Thread th1 = new DataInput();
Thread th2 = new CountDown();
th1.start();
th2.start();
}
}
// 데이터를 입력하는 쓰레드
class DataInput extends Thread{
// 입력 여부를 확인하기 위한 변수 선언
// 쓰레드에서 공통으로 사용할 변수
public static boolean inputCheck = false; //static으로 만들어서 올라가 있음
@Override
public void run() {
String str = JOptionPane.showInputDialog("아무거나 입력하세요");
inputCheck = true; //입력이 완료되면 true로 변경
System.out.println("입력값 : " + str);
}
}
//카운트 다운을 진행하는 쓰레드
class CountDown extends Thread{
@Override
public void run() {
for (int i = 10; i >= 1; i--) {
System.out.println(i);
//입력이 완료되었는지 여부를 검사해서 입력이 완료되면 쓰레드를 종료시킨다.
if(DataInput.inputCheck==true){
return;//멈춘이유
}
try {
Thread.sleep(1000);//1000이면 1초, 100이면 0.1초
} catch (InterruptedException e) {
// TODO: handle exception
}
}
System.out.println("10초가 지났습니다. 프로그램을 종료합니다.");
System.exit(0);
}
}