Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 제네릭
- 컬렉션프레임워크
- 참조형변수
- 정수형타입
- oracle
- GRANT VIEW
- 예외미루기
- EnhancedFor
- 자바
- cursor문
- 메소드오버로딩
- 추상메서드
- 컬렉션 타입
- 어윈 사용법
- 인터페이스
- 객체 비교
- abstract
- 예외처리
- 자동차수리시스템
- NestedFor
- 오라클
- 다형성
- 생성자오버로드
- Java
- 집합_SET
- 한국건설관리시스템
- 대덕인재개발원
- exception
- 환경설정
- 사용자예외클래스생성
Archives
- Today
- Total
거니의 velog
230901_스레드 4 본문
[HorseGame.java]
package kr.or.ddit.basic;
import java.util.Arrays;
/*
10마리의 말들이 경주하는 프로그램을 작성하시오.
말은 Horse라는 이름의 쓰레드 클래스로 작성하는데 이 클래스는 말이름(String), 등수(int), 현재위치(int)를
멤버변수로 갖는다. 그리고 이 클래스에는 등수를 오름차순으로 정렬할 수 있는 내부 정렬 기준이 있다.
(Comparable 인터페이스 구현)
조건)
1) 경기 구간은 1 ~ 50구간으로 되어 있다.
2) 경기가 끝나면 등수 순으로 출력한다.
3) 경기 중에는 중간 중간에 각 말들의 위치를 아래와 같이 나타내 준다.
예시)
01번말 : --->-----------------------------------
02번말 : ------->-------------------------------
...
10번말 : ----->---------------------------------
*/
public class HorseGame {
public static void main(String[] args) {
Horse2[] horses = new Horse2[] {
new Horse2("01번말"),
new Horse2("02번말"),
new Horse2("03번말"),
new Horse2("04번말"),
new Horse2("05번말"),
new Horse2("06번말"),
new Horse2("07번말"),
new Horse2("08번말"),
new Horse2("09번말"),
new Horse2("10번말")
};
GameBoard gb = new GameBoard(horses);
// 경주 시작 ==> 쓰레드 시작
for(Horse2 h : horses) {
h.start();
}
gb.start(); // 말의 현재 위치 출력용 쓰레드 실행
// 모든 말의 경주가 끝날 때까지 기다린다.
for(Horse2 h : horses) {
try {
h.join();
} catch (InterruptedException e) {
// TODO: handle exception
}
}
try {
gb.join();
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println();
System.out.println("경기 끝......");
System.out.println();
// 등수의 오름차순으로 정렬한다.
Arrays.sort(horses);
System.out.println("=== 경기 결과 ===");
for(Horse2 h : horses) {
System.out.println(h);
}
}
}
//말은 Horse라는 이름의 쓰레드 클래스로 작성하는데 이 클래스는 말이름(String), 등수(int), 현재위치(int)를
//멤버변수로 갖는다. 그리고 이 클래스에는 등수를 오름차순으로 정렬할 수 있는 내부 정렬 기준이 있다.
//(Comparable 인터페이스 구현)
class Horse2 extends Thread implements Comparable<Horse2> {
// 등수를 구하기 위한 변수(각 말들<쓰레드들>이 공통으로 사용한다.)
public static int currentRank = 0;
private String horseName; // 말이름
private int rank; // 등수
private int location; // 현재 위치
// 생성자
public Horse2(String horseName) {
this.horseName = horseName;
}
public String getHorseName() {
return horseName;
}
public void setHorseName(String horseName) {
this.horseName = horseName;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
public int getLocation() {
return location;
}
public void setLocation(int location) {
this.location = location;
}
@Override
public String toString() {
return "경주마 " + horseName + "은(는) " + rank + "등 입니다.";
}
// 등수의 오름차순으로 정렬하는 정렬 기준 구성하기
@Override
public int compareTo(Horse2 horse) {
return Integer.compare(this.rank, horse.getRank());
}
@Override
public void run() {
// 경기 구간은 1 ~ 50 구간으로 되어 있다.
for(int i=1; i<=50; i++) {
this.location = i; // 말의 현재 위치를 저장한다.
try {
Thread.sleep((int)(Math.random() * 500 + 1)); // 1 ~ 500 사이의 난수
} catch (InterruptedException e) {
// TODO: handle exception
}
}
// 현재 말의 경기가 끝난다. ==> 등수를 구해서 저장한다.
currentRank++;
this.rank = currentRank;
}
}
//예시)
//01번말 : --->-----------------------------------
//02번말 : ------->-------------------------------
//...
//10번말 : ----->---------------------------------
class GameBoard extends Thread {
private Horse2[] horses;
// 생성자
public GameBoard(Horse2[] horses) {
this.horses = horses;
}
@Override
public void run() {
while(true) {
// 모든 말들의 경기가 종료되었는지 여부를 검사한다.
if(Horse2.currentRank == horses.length) {
break;
}
// 각 텀 사이의 빈 줄 출력
for(int i=1; i<=15; i++) {
System.out.println();
}
// System.out.println("**************************************************************************");
for(Horse2 h : horses) {
// 01번말 : --->-----------------------------------
System.out.print(h.getHorseName() + " : ");
for(int i=1; i<=50; i++) {
if(h.getLocation() == i) { // 말의 현재 위치 확인
System.out.print(">");
}else {
System.out.print("-");
}
}
System.out.println(); // 줄바꿈.
}
// System.out.println("**************************************************************************");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO: handle exception
}
}
}
}
[ThreadTest13.java]
package kr.or.ddit.basic;
/*
* Thread의 stop()메서드를 호출하면 쓰레드가 바로 멈춘다.
* 이 때 사용하던 자원을 정리하지 못하고 쓰레드가 종료되어
* 다른 쓰레드의 실행에 영향을 줄 수 있다.
* 그래서 stop()메서드는 비추천으로 되어 있다.
*/
public class ThreadTest13 {
public static void main(String[] args) {
ThreadStopTest01 th1 = new ThreadStopTest01();
th1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO: handle exception
}
// th1.stop();
th1.setStop(true);
}
}
// 쓰레드를 멈추게 하는 연습용 쓰레드
class ThreadStopTest01 extends Thread {
private boolean stop;
public void setStop(boolean stop) {
this.stop = stop;
}
@Override
public void run() {
while(!stop) {
System.out.println(" 쓰레드의 처리내용 실행 중... ");
}
System.out.println("사용하던 자원을 정리한다...");
System.out.println("쓰레드 종료...");
}
}
package kr.or.ddit.basic;
/*
* Thread의 stop()메서드를 호출하면 쓰레드가 바로 멈춘다.
* 이 때 사용하던 자원을 정리하지 못하고 쓰레드가 종료되어
* 다른 쓰레드의 실행에 영향을 줄 수 있다.
* 그래서 stop()메서드는 비추천으로 되어 있다.
*/
public class ThreadTest13 {
public static void main(String[] args) {
/*
ThreadStopTest01 th1 = new ThreadStopTest01();
th1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO: handle exception
}
// th1.stop();
th1.setStop(true);
*/
ThreadStopTest02 th2 = new ThreadStopTest02();
th2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO: handle exception
}
th2.interrupt();
}
}
// 쓰레드를 멈추게 하는 연습용 쓰레드
class ThreadStopTest01 extends Thread {
private boolean stop;
public void setStop(boolean stop) {
this.stop = stop;
}
@Override
public void run() {
while(!stop) {
System.out.println(" 쓰레드의 처리내용 실행 중... ");
}
System.out.println("사용하던 자원을 정리한다...");
System.out.println("쓰레드 종료...");
}
}
// interrupt() 메서드를 이용하여 쓰레드를 멈추게 하는 연습용 쓰레드
class ThreadStopTest02 extends Thread {
@Override
public void run() {
/*
// 방법1 ==> interrupt()메서드와 sleep()메서드를 이용하는 방법
try {
while(true) {
System.out.println("쓰레드 실행 중...");
Thread.sleep(1);
}
} catch (InterruptedException e) {
// TODO: handle exception
}
*/
// 방법2
while(true) {
System.out.println("Thread 실행 중...");
// interrupt()메서드가 호출되었는지 여부를 검사한다.
/*
// 검사방법1 ==> 쓰레드의 인스턴스 메서드 중 isInterrupted() 메서드를 이용한다.
// isInterrupted() 메서드 ==> interrupt() 메서드가 호출되면 true를 반환한다.
if(this.isInterrupted()) {
break;
}
*/
// 검사방법2 ==> 쓰레드의 정적(static) 메서드인 interrupted() 메서드를 이용한다.
// interrupted() 메서드 ==> interrupt() 메서드가 호출되면 true를 반환한다.
if(Thread.interrupted()) {
break;
}
}
System.out.println();
System.out.println("자원 정리...");
System.out.println("쓰레드 끝.........");
}
}
[interrupt() 메서드 적용한 코드]
package kr.or.ddit.basic;
import java.util.Arrays;
/*
10마리의 말들이 경주하는 프로그램을 작성하시오.
말은 Horse라는 이름의 쓰레드 클래스로 작성하는데 이 클래스는 말이름(String), 등수(int), 현재위치(int)를
멤버변수로 갖는다. 그리고 이 클래스에는 등수를 오름차순으로 정렬할 수 있는 내부 정렬 기준이 있다.
(Comparable 인터페이스 구현)
조건)
1) 경기 구간은 1 ~ 50구간으로 되어 있다.
2) 경기가 끝나면 등수 순으로 출력한다.
3) 경기 중에는 중간 중간에 각 말들의 위치를 아래와 같이 나타내 준다.
예시)
01번말 : --->-----------------------------------
02번말 : ------->-------------------------------
...
10번말 : ----->---------------------------------
*/
public class HorseGame {
public static void main(String[] args) {
Horse2[] horses = new Horse2[] {
new Horse2("01번말"),
new Horse2("02번말"),
new Horse2("03번말"),
new Horse2("04번말"),
new Horse2("05번말"),
new Horse2("06번말"),
new Horse2("07번말"),
new Horse2("08번말"),
new Horse2("09번말"),
new Horse2("10번말")
};
GameBoard gb = new GameBoard(horses);
// 경주 시작 ==> 쓰레드 시작
for(Horse2 h : horses) {
h.start();
}
gb.start(); // 말의 현재 위치 출력용 쓰레드 실행
// 모든 말의 경주가 끝날 때까지 기다린다.
for(Horse2 h : horses) {
try {
h.join();
} catch (InterruptedException e) {
// TODO: handle exception
}
}
gb.interrupt();
try {
gb.join();
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println();
System.out.println("경기 끝......");
System.out.println();
// 등수의 오름차순으로 정렬한다.
Arrays.sort(horses);
System.out.println("=== 경기 결과 ===");
for(Horse2 h : horses) {
System.out.println(h);
}
}
}
//말은 Horse라는 이름의 쓰레드 클래스로 작성하는데 이 클래스는 말이름(String), 등수(int), 현재위치(int)를
//멤버변수로 갖는다. 그리고 이 클래스에는 등수를 오름차순으로 정렬할 수 있는 내부 정렬 기준이 있다.
//(Comparable 인터페이스 구현)
class Horse2 extends Thread implements Comparable<Horse2> {
// 등수를 구하기 위한 변수(각 말들<쓰레드들>이 공통으로 사용한다.)
public static int currentRank = 0;
private String horseName; // 말이름
private int rank; // 등수
private int location; // 현재 위치
// 생성자
public Horse2(String horseName) {
this.horseName = horseName;
}
public String getHorseName() {
return horseName;
}
public void setHorseName(String horseName) {
this.horseName = horseName;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
public int getLocation() {
return location;
}
public void setLocation(int location) {
this.location = location;
}
@Override
public String toString() {
return "경주마 " + horseName + "은(는) " + rank + "등 입니다.";
}
// 등수의 오름차순으로 정렬하는 정렬 기준 구성하기
@Override
public int compareTo(Horse2 horse) {
return Integer.compare(this.rank, horse.getRank());
}
@Override
public void run() {
// 경기 구간은 1 ~ 50 구간으로 되어 있다.
for(int i=1; i<=50; i++) {
this.location = i; // 말의 현재 위치를 저장한다.
try {
Thread.sleep((int)(Math.random() * 500 + 1)); // 1 ~ 500 사이의 난수
} catch (InterruptedException e) {
// TODO: handle exception
}
}
// 현재 말의 경기가 끝난다. ==> 등수를 구해서 저장한다.
currentRank++;
this.rank = currentRank;
}
}
//예시)
//01번말 : --->-----------------------------------
//02번말 : ------->-------------------------------
//...
//10번말 : ----->---------------------------------
class GameBoard extends Thread {
private Horse2[] horses;
// 생성자
public GameBoard(Horse2[] horses) {
this.horses = horses;
}
@Override
public void run() {
while(true) {
// 모든 말들의 경기가 종료되었는지 여부를 검사한다.
// if(Horse2.currentRank == horses.length) {
// break;
// }
// interrupt()메서드를 이용한 종료 처리
if(this.isInterrupted()) {
break;
}
// 각 텀 사이의 빈 줄 출력
for(int i=1; i<=15; i++) {
System.out.println();
}
// System.out.println("**************************************************************************");
for(Horse2 h : horses) {
// 01번말 : --->-----------------------------------
System.out.print(h.getHorseName() + " : ");
for(int i=1; i<=50; i++) {
if(h.getLocation() == i) { // 말의 현재 위치 확인
System.out.print(">");
}else {
System.out.print("-");
}
}
System.out.println(); // 줄바꿈.
}
// System.out.println("**************************************************************************");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
this.interrupt();
}
}
}
}
[ThreadTest14.java]
package kr.or.ddit.basic;
// 쓰레드에서 객체를 공통으로 사용하는 예제
/*
* 원주율을 계산하는 쓰레드와
* 계산된 원주율을 출력하는 쓰레드가 있다.
*
* 원주율을 관리하는 객체가 필요하다.
* 이 객체를 두 스레드에서 공통으로 사용해서 처리한다.
*/
public class ThreadTest14 {
public static void main(String[] args) {
// 공통으로 사용할 객체 생성
ShareData sd = new ShareData();
// 쓰레드 객체들을 생성하고 공통으로 사용할 객체를 각각의 쓰레드에 주입한다.
CalcPIThread th1 = new CalcPIThread();
th1.setSd(sd);
PrintPIThread th2 = new PrintPIThread(sd);
th1.start();
th2.start();
}
}
// 원주율을 계산하는 쓰레드
class CalcPIThread extends Thread {
private ShareData sd; // 공통으로 사용할 객체의 참조값이 저장될 변수 선언
// 방법1 ==> setter를 이용하여 공통으로 사용할 객체 초기화하기
public void setSd(ShareData sd) {
this.sd = sd;
}
@Override
public void run() {
/*
* 원주율 = (1/1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 ... ) * 4
*
* 분모만 보면 규칙성? 1 - 3 + 5 - 7 + 9 - 11 ...
*
* 2로 나눈 몫 ? 0 - 1 + 2 - 3 + 4 - 5 ...
*/
double sum = 0.0;
for(int i=1; i<=2_000_000_000; i+=2) {
if( (i/2) % 2 == 0 ) { // 몫이 짝수일 때
sum += (1.0 / i);
}else { // 몫이 홀수일 때
sum -= (1.0 / i);
}
}
sd.result = sum * 4; // 계산 결과를 공통객체의 result 변수에 저장한다.
sd.isOk = true; // 계산이 완료됨을 설정한다.
}
}
// 계산이 완료되면 계산된 원주율을 출력하는 쓰레드
class PrintPIThread extends Thread {
private ShareData sd; // 공통으로 사용할 객체의 참조값이 저장될 변수 선언
// 방법2 ==> 생성자를 이용하여 공통으로 사용할 객체 초기화하기
public PrintPIThread(ShareData sd) {
this.sd = sd;
}
@Override
public void run() {
while(true) {
if(sd.isOk == true) { // 계산이 완료되면 반복문을 빠져 나온다.
break;
}
}
// 계산된 결과를 출력한다.
System.out.println();
System.out.println("원주율 계산 결과 : " + sd.result);
System.out.println("Math.PI : " + Math.PI);
}
}
// 원주율을 관리하는 객체 (공통으로 사용할 객체)
class ShareData {
public double result; // 계산된 원주율이 저장될 변수
public volatile boolean isOk; // 계산이 완료되었는지 여부를 나타내는 변수
// volatile ==> CPU의 각 코어에 캐시가 있는데 이 캐시를 사용하지 않고 직접 메모리에서 데이터값을 입출력하도록 한다.
}
[ThreadTest15.java]
package kr.or.ddit.basic;
public class ThreadTest15 {
public static void main(String[] args) {
ShareObject sObj = new ShareObject(); // 공통 객체 생성
TestThread th1 = new TestThread("test1", sObj);
TestThread th2 = new TestThread("test2", sObj);
th1.start();
th2.start();
}
}
class TestThread extends Thread {
private ShareObject sObj;
public TestThread(String name, ShareObject sObj) {
super(name); // 쓰레드의 name 설정
this.sObj = sObj;
}
@Override
public void run() {
for(int i=0; i<10; i++) {
sObj.add();
}
}
}
// 공통으로 사용할 객체
class ShareObject {
private int sum = 0;
//public synchronized void add() { // 방법1 ==> 메서드에 동기화 설정을 한다.
public void add() {
synchronized (this) { // 방법2 == 동기화 블럭을 이용하여 설정한다.
int n = sum;
n += 10; // 10 증가
sum = n;
System.out.println(Thread.currentThread().getName() + " 합계 : " + sum);
}
}
}
'대덕인재개발원_자바기반 애플리케이션' 카테고리의 다른 글
230905_입출력 1 (0) | 2023.09.04 |
---|---|
230904_스레드 5 (0) | 2023.09.04 |
230831_스레드 3 (0) | 2023.08.31 |
230830_스레드 2 (0) | 2023.08.29 |
230829_스레드 1 (0) | 2023.08.29 |