예외처리
- 예외가 발생하는 경우
- 정수를 0으로 나누는 경우 / 배열의 첨자가 범위를 벗어났을 경우 / 부적절한 형 변환이 발생한 경우 / 입출력 시 인터럽트가 발생한 경우 / 지정한 파일일 존재하지 않는 경우 등 - 에러 발생 시 에러 메시지를 출력하기 위해 제공 되는 메서드
- getMessage() : 해당 객체에 포함된 에러 메시지
- toString() : 예외 클래스와 해당 객체에 포함된 에러 메시지
- printStackTrace() : 예외가 발생하기까지의 메소드 호출 순서를 화면에 출력 - 다중 try - catch - finally
try{
예외를 발생시킬 가능성이 있는 문장들;
}catch(예외 타입1){
예외 타입1 발생 시 처리할 문장들;
}catch(예외 타입2){
예외 타입2 발생 시 처리할 문장들;
}finally{
항상 실행할 문장들;
} - throws
- 예외가 발생한 메소드를 호출한 곳으로 예외 처리를 넘겨준다.
- throws 사용시 반드시 try - catch 문으로 예외 사항 처리해야함
- 접근 제한자 메소드 이름() throws 예외 클래스 이름들 { // 메소드가 수행 할 작업들; } - 반드시 예외 사항 처리 필요한 곳
- 파일 입출력, 메모리 입출력, 데이터 베이스 입출력, 네트워크 입출력
예외 처리 클래스
- IOException 클래스
- 데이터를 입출력할 때 발생할 수 있는 에러 이벤트를 처리하는 클래스 - NullPointerException 클래스
- 참조할 메모리가 없을 경우 발생하는 이벤트를 처리하는 클래스 - ArrayIndexOutOfBoundsException 클래스
- 배열의 범위를 벗어났을 때 발생하는 이벤트를 처리하는 클래스 - FileNotFoundException 클래스
- 처리할 파일이 없을 경우 발생하는 이벤트를 처리하는 클래스 - Exception 클래스
- 모든 예외 처리 클래스의 상위 클래스
스레드
- 스레드 : 어떠한 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위
- 자바 스레드 지원되므로 멀티스레드를 쉽게 구현가능하고, 안정성과 효율성을 보장할 수 있다.
- main()도 하나의 스레드이다.
Thread 클래스를 상속하는 방법
작성 순서 | 사용 예 |
1. 스레드 클래스 생성 - Thread 클래스 상속 - 스레드 기능 구현 : run()구현 |
public class FThread extends Thread{ public void run(){ // 처리 내용 } } |
2. 스레드 객체 생성 - new 연산자 |
FThread th = new FThread(); |
3. 스레드 실행 - start() 메소드 호출 |
th.start(); |
class DerivedThread extends Thread{
public void run(){
for(int i=0; i<50; i++)
System.out.print(i + "\t");
}
}
public class ThreadEx{
public static void main(String[] args){
System.out.println("프로그램 시작");
DerivedThread d1 = new DerivedThread();
DerivedThread d2 = new DerivedThread();
d1.start();
d2.start();
System.out.println("프로그램 종료");
// d1, d2, 프로그램 종류 메시지가 전부 번갈아 가며 실행된다.
// 실행될 때마다 다른 결과 나옴
// Thread Scheduler가 실행 시간과 순서를 관리하기 때문
}
}
Runnable 인터페이스를 구현하는 방법
- Thread 클래스를 상속하는 방법과 큰 차이는 없지만 Thread 클래스를 상속받는 것이 더 편리하다.
- 만약 다른 클래스를 상속하는 경우 다중상속을 지원하지 않기 때문에 인터페이스를 구현하여 스레드 프로그램 작성
작성 순서 | 사용 예 |
1. 스레드 클래스 생성 - Runnable 인터페이스를 구현 - 스레드 기능 구현 : run() 구현 |
public class SThread implements Runnable{ public void run(){ // 처리 내용 } } |
2. 스레드 객체 생성 - new 연산자 |
SThread st = new SThread(); Thread th = new Thread(st); // Thread th = new Thread(new STread()); |
3. 스레드 실행 - start() 메소드 호출 |
th.start(); |
class Top implements Runnable{
public void run(){
for(int i=0; i<50; i++)
System.out.println(i);
}
}
public class Runnable2Ex{
public static void main(String[] args){
System.out.println("프로그램 시작");
// Runnable 구현 객체 만들기
Top t = new Top();
Thread th1 = new Thread(t);
Thread th2 = new Thread(t);
th1.start();
th2.start();
System.out.println("프로그램 종료");
}
}
스레드의 상태
- start 상태
- 시작 상태 ( start() 메서드 호출했을 때 )
- Runnable 상태로 변한다. - Runnable 상태
- 동작할 수 있는 상태
- 여러개 스레드 존재 가능 - Run 상태
- 동작 상태 ( Runnable 상태에서만 Run 상태가 될 수 있다. )
- 하나의 스레드만 동작 가능 - NotRunnable 상태
- 대기 상태
- Run 상태로 진입할 수는 없지만 Dead 상태는 아니다. - Dead 상태
- 종료 상태
- run() 메소드의 종료 = 스레드 종료 - 스레드 제어 메소드
- sleep(시간) 메소드 : 일정 시간 동안 NotRunnable 상태가 되었다 Runnable 상태가 된다. ( 시간 단위 : 1/1000초 )
- wait() 메소드 : NotRunnable 상태가 됨.
- notify() 메소드 : Runnable 상태가 됨
스레드 우선순위
- 우선순위(priority)
- 어떤 스레드를 더 먼저 실행할 수 있는 권한
- 여러 매소드 중 우선순위가 높은 스레드 실행 - 우선권 상수
- public static final int MAX_PRIORITY // 가장 높다, 10
- public static final int MIN_PRIORITY // 가장 낮다, 1
- public static final int NORM_PRIORITY // 중간, 5 - 메소드
- public final int getPriority() : 우선 순위를 얻어오는 메소드
- public final void setPriority(int newPriority) : 우선 순위를 지정하는 메소드
- public final void setName(String name) : 스레드 이름 지정하는 메소드
- public final String getName() : 스레드 이름 얻어오는 메소드
class Top implements Runnable{
public void run(){
for(int i=0; i<30; i++)
System.out.print((Thread.currentThread()).getName() + i + "\t");
// 현재 실행되는 스레드의 이름 + i + "\t"
}
}
public class Runnable3Ex{
public static void main(String[] args){
System.out.println("프로그램 시작");
Top p = new Top();
Thread th1 = new Thread(p, "a"); // 스레드 생성 + 이름 지정
Thread th2 = new Thread(p, "b");
th1.setName("new_a"); // 스레드 이름 변경
th2.setName("new_b");
th1.setPriority(9); // 스레드 우선 순위 변경
th2.setPriority(th2.MIN_PRIORITY);
System.out.println(th1.getPriority()); // 우선 순위 출력
System.out.println(th1.getPriority());
th1.start(); // 스레드 시작
th2.start();
System.out.println("프로그램 종료");
}
}
스레드 동기화
- 동기화(Synchronization)
- 하나의 스레드가 끝날 때까지 락(lock)을 걸어서 다른 스레드가 동일한 데이털르 갱신하지 못하도록 하는 것.
- synchronized 키워드를 이용해 동기화
- 동기화된 메소드는 락을 설정하여 완료될 때까지 유지하며, 동시에 호출할 수 없다. - 메소드 전체를 동기화 하는 방법
접근제한자 synchronized 반환형 메소드이름( 인자 ) { 실행 코드 }
// 두개의 스레드가 독립적으로 합을 구하는 프로그램
class Summing{
private int sum;
public synchronized void sumTo(int num){ // 메소드 전체를 동기화
sum = 0;
for(int i=1; i<=num; i++){
sum += i;
System.out.print("스레드 : " + Thread.currentThread().getName());
System.out.println("의 1 ~ " + i + "까지의 합은 " + sum);
try{
Thread.sleep(500); // 0.5초
}catch(InterruptedException e){}
}
}//sumTo
public int getSum(){ return sum; }
}
class MultiThreadEx extends Thread{
private Summing sum;
private int num;
public MultiThreadEx(String s, Summing sum, int num){
super(s);
this.sum = sum;
this.num = num;
System.out.println("스레드 : " + this.getName() + "가 시작됨");
}
public void run(){
sum.sumTo(num);
System.out.println("스레드 : " + this.getName() + "가 종료됨");
}
public static void main(String[] args){
Summing sum = new Summing();
MultiThreadEx a = new MultiThreadEx("A", sum, 5);
MultiThreadEx b = new MultiThreadEx("B", sum, 5);
a.setPriority(8);
b.setPriority(10);
a.start();
b.start();
}
}
- 특정 블록을 지정하여 객체를 동기화하는 방법
synchronized( 객체 변수 ){ 실행 코드 }
// 공동으로 사용하는 통장에 각자 카드를 가질 때 자유롭게 입출금 할 수 있는 프로그램
class Bank{
private int money = 10000;
public int getMoney(){ return this.money; }
public void setMoney(int money){ this.money = money; }
public void saveMoney(int save){
int m = this.getMoney();
try{
Thread.sleep(500);
}catch(InterruptedException e){
e.printStackTrace();
}
this.setMoney(m + save);
}
public void minusMoney(int minus){
int m = this.getMoney();
try{
Thread.sleep(500);
}catch(InterruptedException e){
e.printStackTrace();
}
this.setMoney(m - minus);
}
}
class Family1 extends Thread{
public void run(){
synchronized(BankEx.mybank){ // 특정 블록을 지정하여 객체를 동기화
BankEx.mybank.saveMoney(5000);
}
System.out.println("saveMoney(5000) : " + BankEx.mybank.getMoney());
}
}
class Family2 extends Thread{
public void run(){
synchronized(BankEx.mybank){ // 특정 블록을 지정하여 객체를 동기화
BankEx.mybank.minusMoney(2000);
}
System.out.println("minusMoney(2000) : " + BankEx.mybank.getMoney());
}
}
public class BankEx{
public static Bank mybank = new Bank();
public static void main(String[] args){
System.out.println("원금 : " + mybank.getMoney());
Family1 f1 = new Family1();
Family2 f2 = new Family2();
f1.start();
try{
Thread.sleep(200);
}catch(InterruptedException e){
e.printStackTrace();
}
f2.start();
}
}
'전공' 카테고리의 다른 글
파이썬_모듈, 패키지 (2) | 2024.12.19 |
---|---|
자료구조_알고리즘 (1) | 2024.12.17 |
Java_컬렉션 제네릭 (7) | 2024.10.08 |
파이썬_변수, 자료형 / 제어문, 반복문 / 함수 (0) | 2024.07.10 |
자료구조_비선형 구조 (0) | 2024.07.09 |