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 | 31 |
Tags
- oracle
- 한국건설관리시스템
- 인터페이스
- 생성자오버로드
- NestedFor
- 정수형타입
- EnhancedFor
- 객체 비교
- 예외미루기
- 제네릭
- abstract
- 참조형변수
- 오라클
- GRANT VIEW
- 메소드오버로딩
- exception
- 어윈 사용법
- 다형성
- 집합_SET
- 컬렉션 타입
- 자바
- 컬렉션프레임워크
- cursor문
- 예외처리
- 대덕인재개발원
- 사용자예외클래스생성
- 추상메서드
- Java
- 환경설정
- 자동차수리시스템
Archives
- Today
- Total
거니의 velog
230904_스레드 5 본문
[ThreadTest16.java]
package kr.or.ddit.basic;
// 은행의 입출금을 쓰레드로 처리하는 예제
public class ThreadTest16 { // 공통 객체
private int balance; // 잔액이 저장될 변수
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
// 입금을 처리하는 메서드
public void deposit(int money) {
balance += money;
}
// 출금을 처리하는 메서드 (반환값 : 출금 성공 => true, 출금 실패 => false)
public synchronized boolean withdraw(int money) {
if(balance >= money) {
for(int i=1; i<=100000000; i++) { // 시간 지연용
int a = i + 3;
}
balance -= money;
System.out.println("메서드 안에서 balance = " + balance);
return true;
}else {
return false;
}
}
public static void main(String[] args) {
ThreadTest16 account = new ThreadTest16();
account.setBalance(10000); // 잔액을 10000원으로 셋팅
// 익명 구현체로 쓰레드 구현
Runnable test = new Runnable() {
@Override
public void run() {
boolean result = account.withdraw(6000); // 6000원 출금하기
System.out.println("쓰레드 안에서 result = " + result + ", 잔액 = " + account.getBalance());
}
};
//----------------------------------------------------
// 익명 구현체를 이용한 Thread 객체 생성
Thread th1 = new Thread(test);
Thread th2 = new Thread(test);
th1.start();
th2.start();
}
}
[ThreadTest17.java]
package kr.or.ddit.basic;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
public class ThreadTest17 {
private static Vector<Integer> vec = new Vector<Integer>();
// 동기화 처리가 되지 않은 List
private static List<Integer> list1 = new ArrayList<Integer>();
public static void main(String[] args) {
// 익명 구현체로 쓰레드 구현
Runnable r = new Runnable() {
@Override
public void run() {
for(int i=0; i<10000; i++) {
// vec.add(i);
list1.add(i);
}
}
};
//----------------------------------------
Thread[] thArr = new Thread[] {
new Thread(r),
new Thread(r),
new Thread(r),
new Thread(r),
new Thread(r)
};
for(Thread th : thArr) {
th.start();
}
for(Thread th : thArr) {
try {
th.join();
} catch (InterruptedException e) {
// TODO: handle exception
}
}
// System.out.println("vec의 개수 : " + vec.size()); // vec의 개수 : 50000, 내부적으로 동기화 처리가 잘 되어 있음.
System.out.println("list1의 개수 : " + list1.size()); // 내부적으로 동기화 처리가 안되어 있어서 오류가 남.
// ArrayList도 배열과 같다. 기본적 크기는 10개. 그리고 데이터 추가하면서 10개가 넘어가면 현재 크기의 2배로 만듦.
// add() 메서드가 배열의 크기가 새로 넣을 데이터보다 작으면 배열 크기를 늘리고 넣음.
// 쓰레드로 작업하면 여러 쓰레드가 동작하므로 원래 데이터 크기가 부족해서 큰 배열 만들고 원래 데이터 복사하는 와중에 다른 쓰레드로 제어가 넘어가면 배열 크기가 크므로 그냥 데이터 추가해버림. 이런 식의 반복.
}
}
synchronized 메서드1() {
~~~
wait();
~~~
}
synchronized 메서드2() {
~~~
notify();
~~~
}
[ThreadTest18.java]
package kr.or.ddit.basic;
/*
* wait(), notify()를 이용한 두 쓰레드에서 번갈아 한번씩 실행하는 예제
* ( wait(), notify(), notifyAll()은 동기화 영역에서만 사용 가능하다. )
*/
public class ThreadTest18 {
public static void main(String[] args) {
WorkObject workObj = new WorkObject();
ThreadA thA = new ThreadA(workObj);
ThreadB thB = new ThreadB(workObj);
thA.start();
thB.start();
}
}
// 공통으로 사용할 class
class WorkObject {
public synchronized void methodA() {
System.out.println("methodA() 메서드 실행 중...");
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
// TODO: handle exception
}
}
public synchronized void methodB() {
System.out.println("methodB() 메서드에서 작업 중...");
notify();
try {
wait();
} catch (InterruptedException e) {
// TODO: handle exception
}
}
}
// WorkObject의 methodA() 메서드만 호출하는 쓰레드
class ThreadA extends Thread {
private WorkObject workObj;
// 생성자
public ThreadA(WorkObject workObj) {
this.workObj = workObj;
}
@Override
public void run() {
for(int i=1; i<=10; i++) {
workObj.methodA();
}
synchronized (workObj) {
workObj.notify();
}
}
}
//WorkObject의 methodB() 메서드만 호출하는 쓰레드
class ThreadB extends Thread {
private WorkObject workObj;
// 생성자
public ThreadB(WorkObject workObj) {
this.workObj = workObj;
}
@Override
public void run() {
for(int i=1; i<=10; i++) {
workObj.methodB();
}
synchronized (workObj) {
workObj.notify();
}
}
}
[ThreadTest19.java]
package kr.or.ddit.basic;
public class ThreadTest19 {
public static void main(String[] args) {
// 공통 객체 생성
DataBox box = new DataBox();
ProducerThread th1 = new ProducerThread(box);
ConsumerThread th2 = new ConsumerThread(box);
th1.start();
th2.start();
}
}
// 데이터를 공통으로 사용하는 class
class DataBox {
private String value;
/*
* value값이 null이면 value에 문자열이 채워질 때까지 기다리고
* value에 값이 있으면 해당 문자열을 반환한다.
* (이 때, 반환 후에는 value값을 null로 만든다.)
*/
public synchronized String getValue() {
if(value == null) {
try {
wait();
} catch (InterruptedException e) {
// TODO: handle exception
}
}
// value에 데이터가 있을 때의 처리 내용을 작성한다.
String temp = value;
System.out.println("쓰레드가 읽은 데이터 : " + temp);
value = null;
notify();
return temp;
}
/*
* value변수에 값이 있으면 value가 null이 될 때까지 기다린다.
* value가 null이 되면 새로운 데이터값을 value에 저장한다.
*/
public synchronized void setValue(String value) {
if(this.value != null) {
try {
wait();
} catch (InterruptedException e) {
// TODO: handle exception
}
}
// this.value의 값이 null일 때 처리하는 내용을 작성한다.
this.value = value;
System.out.println("Thread에서 새로 저장한 데이터 : " + value);
notify();
}
}
// 데이터를 넣어주는 쓰레드
class ProducerThread extends Thread {
private DataBox box;
// 생성자
public ProducerThread(DataBox box) {
this.box = box;
}
@Override
public void run() {
for(int i=1; i<=3; i++) {
box.setValue("저장용 데이터 " + i);
}
}
}
// 데이터를 꺼내서 사용하는 쓰레드
class ConsumerThread extends Thread {
private DataBox box;
// 생성자
public ConsumerThread(DataBox box) {
this.box = box;
}
@Override
public void run() {
for(int i=1; i<=3; i++) {
String data = box.getValue();
}
}
}
'대덕인재개발원 > 대덕인재개발원_자바기반 애플리케이션' 카테고리의 다른 글
230906_입출력 2 (0) | 2023.09.06 |
---|---|
230905_입출력 1 (0) | 2023.09.04 |
230901_스레드 4 (0) | 2023.09.01 |
230831_스레드 3 (0) | 2023.08.31 |
230830_스레드 2 (0) | 2023.08.29 |