1. 예외전달(직접전달, 간접전달)
1-1 예외가 발생될 명령이 선언된 메소드에서 예외처리
형식) try {
예외가 발생될수 있는 명령; ...
} catch(예외클래스 참조변수) {
예외처리명령; ...
} finally {
무조건 실행 명령; ...
}
- try 영역에서 예외가 발생될 경우 예외 인스턴스 생성
- catch 영역에서 예외 인스턴스를 전달받아 예외 처리 - 프로그램 흐름 이동
- catch 영역은 여러 번 선언 가능
- finally 영역에는 예외 발생에 상관없이 무조건 실행될 명령 작성 - 생략가능
1-2 예외가 발생될 명령이 선언된 메소드에서 예외전달
- 예외가 전달된 메소드를 호출할 경우 try 명령을 이용하여 예외를 처리한다.
- 예외를 전달하여 한번에(일괄처리) 예외처리 하고자 할 경우 사용
- throws 키워드를 이용하여 메소드가 명령실행에서 발생될 수 있는 예외를 전달한다.
- " , " 를 이용하여 여러개의 예외전달을 할 수 있다.
- JVM으로 예외가 전달될 경우 자동으로 예외처리가 된다.(함수에서 발생된 예외 -> main메소드에서도 처리하도록 넘김)
형식) 접근지정자 반환형 메소드명(파라메터,...) throws 예외클래스,예외클래스,... {
예외 발생 명령;
}
참고 ) throws -> 발생시켜 전달(시켜서 발생시킨다)한다.(알려주는것) - 뭔가 미리 알려주는것.
throw -> 발생시키는것
** 예외클래스(개발자에 의한 예외클래스작성)를 이용하여 인위적으로 예외를 발생시키는 방법
- Exception클래스를 상속받아 작성한다.
형식) public class 예외클래스 extends Exception {
public 예외클래스() { }
public 예외클래스(String message) {
super(message);
}
}
- if(....조건....) throw new 예외클래스(e.getMessage()); <-이렇게 인위적으로 사용자 정의 예외클래스를 발생시킨다.
checkedExeption | unCheckedExeption | |
처리여부 | 반드시 예외처리를 해야함 RuntimeException을 상속하지 x (예외처리하지 않으면 사용자에게 날것의 메세지를 보낼 수 있으므로 예외처리하는것이 좋다. 예외가 발생하면 쓰레드가 종료되고, 하단명령을 실행시키지 않는다. -> finally를 사용해주어서 무조건 실행되어야 하는 명령을 적어주자) |
예외처리 굳이 하지 않아도 됨 RuntimeException을 상속 |
트랜잭션 롤백 여부 | 롤백 x | 롤백 진행 |
종류 | IOException SQLException |
NullPointerException illegalArgumentException |
2. 단일스레드와 다중스레드
스레드란? 프로세스에서 명령을 실행하는 작업의 단위 (즉, 프로그램의 흐름이란 뜻)
- 메인스레드는 JVM이 한 개만 만들어준다. 그렇다면 나머지 쓰레드는 개발자가 만들어야 한다. ->스레드 인스턴스가 필요하다.
- Thread가 실행하기 위한 명령을 작성하는 run메소드를 오버라이드 선언해준다.
- run 메소드가 종료되면 thread가 소멸된다.
- 스레드 인스턴스 하나당 하나만 만들어짐.
단일 스레드 | 다중 스레드 |
1. JVM에 의해 생성된 스레드를 이용하여 main()메소드의 명령을 실행함 2. main()메소드가 종료되면 자동으로 스레드 종료 |
1. 개발자가 직접스레드를 생성하여 명령을 실행 2. 프로그램의 모든 스레드가 소멸되면 프로그램 종료 |
Thread클래스를 상속받아 스레드를 만드는 방법 | Runnable인터페이스를 상속받아 스레드를 만드는 방법 |
(상속을 받는이유? Thread클래스에는 명령을 실행 할 수 있는 메소드가 없기 때문에 상속받아 오버라이드 하여 사용한다.) | (Runnable을 쓰는이유? 이미 다른 클래슬 상속받았기 때문에 Thread클래스를 상속받지 못함 -> run()메소드를 오버라이드하여 사용) |
1. Thread 인스턴스를 생성하여 새로운 스레드를 생성 2. 생성된 스레드는 자동으로 run()메소드 명령 실행 ★thread인스턴스로 하나의 스레드만 생성가능 3. 스레드 인스턴스로 start() 메소드 호출 |
1. Thread인스턴스를 전달받아 Runnable인스턴스를 생성 2. Thread인스턴스에 run()메소드가 새롭게 구현됨(오버라이드) 3. 스레드 인스턴스로 start() 메소드 호출 |
new MultiOne().start(); | new Thread(new MultiThreadTwo()).start(); |
Thread 우선순위 변경
>> Thread.setPriority(int newPriority) : MIN_1(Thread.MIN_PRIORITY) ~ 10(Thread.MAX_PRIORITY)
다중 스레드 프로그램의 문제점
동일한 클래스로 생성된 여러개의 스레드가 같은 인스턴스의 메소드를 호출할 경우, 메소드 명령에 대한 처리 순서가 불규칙하여 잘못된 결과를 발생시킨다.
다중 스레드 프로그램의 문제점 해결
여러개의 스레드 중 인스턴스 메소드를 먼저 호출한 경우, 메소드의 명령을 끝날때까지 다른 스레드의 메소드 호출을 하지 못하도록 방지하는 방법(Lock 처리) = Syncronized(동기화)를 사용!!!!
동기화는 어떻게 하는가?
- 동기화 메소드 : 메소드에 대한 동기화 처리
- 인스턴스 메소드를 호출하는 명령역역을 Syncronized하는 방법
더보기
멀티스레드 전체 코드 확인하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package site.itwill.thread;
//Thread를 생성하기 위한 클래스
//=> Thread클래스를 상속받아 작성한다.
public class MultiThreadOne extends Thread {
//Thread의 run메소드는 비어있음!!
//Thread가 실행하기 위한 명령을 작성하는 run메소드를 오버라이드 선언.
//★꼭필요
//=>run메소드가 종료되면 Thread가 소멸된다.
@Override
public void run() {
for(char i ='A'; i<= 'Z'; i++) {
System.out.println(i);
try {
Thread.sleep(500);
}catch (InterruptedException e) {
e.getMessage();
}
}
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package site.itwill.thread;
//Thread클래스를 상속받지 못한경우(이미 따른클래스를 상속받는 경우)
//Runnable인터페이스를 상속받아 작성
//=>run()메소드 오버라이드 선언
//별로 권장하지는 않는다.ㅆ
public class MultiThreadTwo implements Runnable {
@Override
public void run() {
for (char i = 'a'; i <= 'z'; i++) {
System.out.println(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.getMessage();
}
}
}
}
|
cs |
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
32
33
34
35
36
|
package site.itwill.thread;
//다중스레드 프로그램
//Thread 인스턴스를 생성하여 새로운 쓰레드를 생성ㅁ 명령을 실행할 수 있도록 한다.
//=>새로운 스레드가 실행된 명령이 작성된 메소드를 Thread인스턴스에 정의해야한다
//=>모든 스레드가 소멸되면 프로그램 종료 - System.exit(0);
public class MultiThreadApp {
public static void main(String[] args) throws InterruptedException {
//Thread thread = new Thread(); //명령을 실행 할 수 있는 메소드가 없음
//Thread클래스를 상속받은 자식클래스로 인스턴스 생성 = Thread인스턴스가 결국 생성
//=>Thread.start() : Thread인스턴스로 새로운 스레드를 생성하는 메소드
//=>생성된 스레드는 자동으로 run 메소드 명령 실행
//=>thread인스턴스로 하나의 스레드만 생성가능 ->그래서 참조변수를 만들을 이유가 없음
new MultiThreadOne().start();
new MultiThreadOne().start();
//Thread인스턴스를 전달받아 Runnable인스턴스를 생성
//=> Thread인스턴스에 run()메소드가 새롭게 구현ㅅ
new Thread(new MultiThreadTwo()).start();
/*
for(char i = 'a'; i <='z'; i++) {
System.out.println(i);
//스레드를 원하는 시간만큼 일시중지 시킬 수 있음
//=>InterruptedException 발생 - 예외처리 필요
Thread.sleep(500);;
}*/
for(int i = 0; i <=9; i++) {
System.out.println(i);
Thread.sleep(500);;
}
}
}
|
cs |
더보기
동기화처리 전체 코드 보기
package site.itwill.thread;
//은행계좌정보를 저장하기 위한 클래스
public class Account {
private int balance; //잔액을 저장하는 변수
public Account() {
// TODO Auto-generated constructor stub
}
public Account(int balance) {
super();
this.balance = balance;
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
//입금메소드와 출금메소드를 만들어준다.
//입금메소드
public synchronized void deposit(String name, int ammount) {
balance += ammount;
System.out.println(name + " 님이 " + ammount +" 원을 입금하셨습니다. 잔액은 "
+ balance +" 원 입니다.");
}
//출금메소드
public void withDraw(String name, int ammount) {
if(balance < ammount) {
System.out.println("[error] " + name + " 님, 잔액이 " + balance + "원 남았습니다." + ammount + " 원 출금할 수 없습니다.");
return;//메소드 종료
}
balance -= ammount;
System.out.println(name + " 님이 " + ammount +" 원을 출금하셨습니다. 잔액은 "
+ balance +" 원 입니다.");
}
}
package site.itwill.thread;
//은행계좌 사용자 정보를 저장하기 위한 클래스
public class AccountUser extends Thread {
private String userName;
private Account account;
public AccountUser() {
// TODO Auto-generated constructor stub
}
public AccountUser(String userName, Account account) {
super();
this.userName = userName;
this.account = account;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
// 입금과 출금을 반복처리 할 수 있도록 하는 메소드
/*
* @Override public void run() { for(int i = 1; i<= 3; i++) {
* account.deposit(userName, 5000); try {
*
* Thread.sleep(1000);
*
* } catch (Exception e) { e.printStackTrace(); }
*
* } }
*/
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
synchronized (account) {
account.withDraw(userName, 3000);
}
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
'💻 수업정리 (2020) > 자바' 카테고리의 다른 글
[5/29] java.util패키지 (0) | 2020.05.29 |
---|---|
[5/28] java.lang패키지 (0) | 2020.05.28 |
[5/26] 접근지정자 , 자료형(클래스, 인터페이스, enum) (0) | 2020.05.26 |
[5/25] abstract 클래스/메소드, 패키지와 인터페이스 (0) | 2020.05.25 |
[5/22] 오버라이드와 객체 형변환 (0) | 2020.05.22 |