15Day - (다중쓰레드)WrapperApp/ StringBufferApp / SingleThreadApp & SingleThread / MultiThreadApp & MultiThreadOne & MultiThreadTwo / Account & AccountUser & AccountUserApp / ConsoleCaluelateApp (숙제)
WrapperApp
// > Byte, Short, Integer, Long, Float, Double, Character, Boolean
// > 원시형 대신객체로 표현하기 위한 사용하는 클래스
/*
int num1 = 100;
int num2 = 200;
int num3 = num1 + num2;
System.out.println("합계 = " + num3);
*/
/*
// Integer 클래스 : 정수값을 저장하기 위한 클래스
// Integer.valueOf(Object i ) : 매개변수로 값을 전달받아 정수값이 저장된 Integer 객체를 반환하는 메소드
Integer num1 = Integer.valueOf(100);
Integer num2 = Integer.valueOf("200"); // 문자열을 전달받아도내부적으로 정수값으로 저장
// Integer num3 = num1.intValue() + num2.intValue(); // Integer객체에 저장된 정수값을 반환하는 메소드
System.out.println("num3 = " + num3.intValue());
*/
// Wrapper 클래스는 오토박싱과 오토언박싱 기능을 제공받아 객체를 생성하거나 사용 가능
// 오토박싱 (AutoBoxting) 원시형 리터럴(값)을 JVM이 자동으로 Wrapper 클래스의 객체로 생성하여 반환하는 기능
// 오토언박싱 : JVM이 Wrapper 클래스의 객체에 저장된 값을 원시형 리터럴로 반환하는 기능
Integer num1 = 100;
Integer num2 = 200;
Integer num3 = num1 + num2;
System.out.println("num3 = " + num3);
num3 = 300
// Integer.valueOf(String s, int radix) : 매개변수로 전달받은 문자열을 원하는 진수의
// 문자열을 정수값으로 변환하여 Intefer 객체에 저장하여 반환하는 메소드
Integer num = Integer.valueOf("ABC", 16); // int num = 0 x ABC;
// Integer 객체에 저장된 정수값을 반환받아 10진수로 출력
System.out.println("num = " + num);
num = 2748
Integer su = 50;
System.out.println("su(10진수) = "+su);
//Integer.toOctalString(int i) : 매개변수로 전달된 정수값을 8진수 형태의 문자열로 변환하여 반환하는 메소드
System.out.println("su(8진수) = "+Integer.toOctalString(su));
// Integer.toHexString(int i) : 매개변수로 전달된 정수값을 16진수 형태의 문자열로 변환하여 반환하는 메소드
System.out.println("su(16진수) = "+Integer.toHexString(su));
// Integer.toBinaryString(int i) : 매개변수로 전달된 정수값을 2진수 형태의 문자열로 변환하여 반환하는 메소드
System.out.println("su(2진수) = "+Integer.toBinaryString(su));
su=-50;
System.out.println("su(2진수) = "+Integer.toBinaryString(su));
su(10진수) = 50
su(8진수) = 62
su(16진수) = 32
su(2진수) = 110010
su(2진수) = 11111111111111111111111111001110
String str1 = "100";
String str2 = "200";
System.out.println("합계 = " + (str1+str2)); // 문자열 결합
// Integer.parseInt(String s) 매개변수로 문자열을 전달받아 정수갑승로 변환하여 반환하는 메소드
// > 정수값으로 변환되지 못하는 문자열이 전달된 경우 NumberFormatException 발생
System.out.println("합계 = "+(Integer.parseInt(str1)+Integer.parseInt(str2)));
}
}
합계 = 100200
합계 = 300
StringBufferApp
// > StringBuffer 객체에 저장된 문자열의 문자 관련 메소드 제공
// > String 객체는 저장된 문자열을 조작하기 위한 메소드 제공X, 조작결과를 반환하는 메소드 제공
// > String 클래스보다 StringBuffer 클래스의 메소드가 문자열 처리 속도가 우수
public class StringBufferApp {
public static void main(String[] args) {
// StringBuffer 클래스는 new 연산자를 생성자를 호출하여 객체 생성
StringBuffer sb = new StringBuffer("ABC");
// StringBuffer.toString() - StringBuffer 객체에 저장된 문자열을 반환하는 메소드
System.out.println("sb.toString() = " + sb.toString());
// StringBuffer 객체가 저장된 참조변수를 출력할 경우 toString 메소드 자동 호출
System.out.println("sb = " + sb);
// StringBuffer 객체에 저장된 문자열을 반환받아 String 객체로 생성하여 참조변수 저장
String str = sb.toString(); // StringBuffer 객체 >> String 객체
System.out.println("str = " + str);
sb.toString() = ABC
sb = ABC
str = ABC
// StringBuffer.append(Object o) - StringBuffer 객체에 저장된 문자열에 매개변수로
// 전달받은 값을 추가하는 메소드
// > String 객체에 저장된 문자열에 += 연산자를 사용한 효과와 동일
sb.append("DEF");
System.out.println("sb = " + sb); //ABCDEF
str += "DEF";
System.out.println("str = " + str);
sb = ABCDEF
str = ABCDEF
// StringBuffer.insert(int index, Object o) : StringBuffer 객체에 저장된 문자열에
// 매개변수로 전달받은 문자열을 원하는 위치(첨자)에 삽입하는 메소드
sb.insert(4, "X");
System.out.println("sb = " + sb); // ABCDXEF
sb = ABCDXEF
// StringBuffer.deleteCharAt(int index) - StringBuffer객체에 저장된 문자열에서
// 매개변수로 전달받은 취이의 문자를 제거하는 메소드
sb.deleteCharAt(2);
System.out.println("sb = " + sb); // ABCDXEF
sb = ABDXEF
// StringBuffer.delete(int beginIndex, int endIndex) : StringBuffer 객체에 저장된
// 문자열에서 매개변수로 전달받은 시작첨자부터 종료첨자 범위의 문자열을 제거하는 메소드
sb.delete(4, 6);
System.out.println("sb = "+sb); // ABDX
sb = ABDX
// StringBuffer.reverse() : StringBuffer 객체에 저장된 문자열의 문자를 역순으로 나열되도록 저장하는 메소드
sb.reverse();
System.out.println("sb = "+sb); // XDBA
}
}
sb = XDBA
SingleThreadApp
// 프로세스 (Process) - 메모리에 저장된 프로그램 - 중앙처리장치(CPU)에 의햐 실행되기 위한 명령
// 단일 스레드 프로그램
// > JVM에 의해 생성된 main 스레드를 이용하여 main() 메소드를 호출하여 명령 실행
// > main() 메소드가 종료되면 main스레드는 자동 소멸 - 프로그램 종료
public class SingleThreadApp {
public static void main(String[] args) {
/*
System.out.println("SingleThreadAppp 클래스의 main() 메소드 시작");
// Thread 클래스 : 스레드 관련 정보를 저장하여 스레드 관련 제어 기능을 메소드로 제공하기 위한 클래스
// Thread.currentThread() : 형재 명령을 읽어 처리하는 스레드에 댜한 Thread객체를 반환하는 메소드
// Thread.getName() : Thread객체에 저장된 스레드의 이름 (고유값)을 반환하는 메소드
System.out.println("["+ Thread.currentThread().getName()
+ "] 스레드에 의해 main() 메소드의 명령 실행");
// 객체를 생성하여 메소드를 호출한 경우 스레드가 메소드로 이동하여 메소드의 명령 실행
// > 메소드의 명령을 모두 실행한 후 다시 현재 위치로 되돌아와 나머지 명령 실행
new SingleThread().dispaly();//객체를 생성하여 직접 메소드 호출
System.out.println("SingleThreadApp 클래스의 main() 메소드 종료");
*/
for(char i='a';i<='z';i++) {
System.out.print(i);
}
}
}
abcdefghijklmnopqrstuvwxyz
SingleThread
public class SingleThread {
public void dispaly() {
/*
System.out.println("SingleThread 클래스의 display() 메소드 시작");
System.out.println("[" + Thread.currentThread().getName()
+ "] 스레드에 의해 SingleThread 클래스의 dispaly() 메소드 명령 실행");
System.out.println("SingleThread 클래스의 disiplay() 메소드 종료");
*/
for(char i='a';i<='z';i++) {
System.out.print(i);
}
}
}
MultiThreadApp
// 다중 스레드 프로그램
// > 프로그램 개발자가 직접 스레드를 생성하여 다수의 명령을 동시에 실행되도록 만든 프로그램
// > 프로그램의 모든 스레드가 소멸돼야만 프로그램 종료
// > GUI 프로그램 및 Web프로그램 등은 다중 스레드 프로그램으로 작성
// 프로그램 개발자가 스레드를 생성하여 명령을 실행하는 방법 -1 : Thread 클래스 이용
// 1.Thread 클래스를 상속받은 자식클래스 작성
// 2.Thread 클래스를 상속받은 자식클래스에서 run() 메소드 오버라이드 선언
// > run() 메소드에는 프로그램 개발자에 의해 생성된 스레드가 실행하기 위한 명령
// 3. Thread 클래스를 상속받은 자식클래스로 객체 생성 - Thread(부모클래스) 객체 생성
// 4. Thread 객체로 start() 메소드 호출 - Thread 객체를 이용하여 새로운 스레드 생성
// > 생성된 스레드는 자동으로 Thread객체의 run()메소드를 호출하여 run()메소드의 명령 실행
// 프로그램 개발자가 스레드를 생성하여 명령을 실행하는 방법 -2 : Runnable 인터페이스 이용
// > 클래스가 이미 다른 클래스를 상속받아 Thread 클래스를 상속받지 못하는 경우
// Runnable 인터페이스를 상속받아 새로운 스레드를 생성하기 위한 방법
// 1.Runnable 인터페이스를 상속받은 자식클래스 작성
// 2.Runnable 인터페이스를 상속받은 자식클래스에서 run() 메소드를 오버라이드 선언
// > run() 메소드에는 프로그램 개발자에 의해 생성된 스레드가 실행하기 위한 명령 작성
// 3.Thread 클래스로 Thread 객체를 생성 - Thread 클래스의 생성자 중 매개변수에 Runnable
// 인터페이스를 상속받은 자식클래스의 객체를 전달하여 Thread 객체를 생성하는 생성자 이용
// 4.Thread 객체로 start() 메소드 호출
public class MultiThreadApp {
// JVM에 의해 main 스레드가 생성되어 main() 메소드를 호출하여 main() 메소드에 작성된 명령실행
// > main()에 의해 전달된 예외는 JVM에 의해 자동으로 예외처리
public static void main(String[] args) throws InterruptedException {
/*
// Thread 클래스로 직접 객체를 생성하여 start() 메소드 호출
// > 새롭게 생성된 메소드는 Thread 객체에 선언된 명령이 없는 run() 메소드 호출 - 무의미
Thread thread=new Thread();
thread.start()
*/
/*
MultiThreadOne one = new MultiThreadOne();
// Thread,start() : Thread객체로 새로운 스레드를 생성하기 위한 메소드
// > 생성된 스레드는 자동으로 Thread객체의 run() 메소드(숨겨진 메소드)를 호출
// > 자식클래스의 오버라이드 선언된 run()메소드가 호출되어 명령 실행
one.start(); // 시작하게됨
// 하나의 Thread객체는 하나의 스레드 생성만 가능
// > Thread 객체를 사용하여 start() 메소드를 여러번 호출할 경우 IllegalThreadStarteEx
// > 다중 스레드 프로그램에서 예외가 발생된 경우 예외가 발생된 스레드만 종료
// one.start();
*/
// Thread 객체를 사용하여 start() 메소드외에 다른 메소드를 호출하지 않을경우 참조변수에 객체를 저장하지 않고
// 객체를 생성하여 직접 메소드 호출
new MultiThreadOne().start();
new MultiThreadOne().start();
new Thread(new MultiThreadTwo()).start();
for (char i = 'A'; i <= 'Z'; i++) {
System.out.print(i);
// Thread.sleep(long ms) - 스레드 객체가 잠/ 매개변수로 전달된 시간(ms)동안 스레드를 일시중지 하는 메소드
// > 메소드에서 InterruptedException 전달 - 일반 예외이므로 예외처리를 하지않으면 에러 발생
Thread.sleep(500); // 0.5초
}
}
}
aaA0bb1B2ccC3ddDe4eE5ffF6ggG7hhH8IiiJj9jKkkllLmMmNnnOooppPqqQrrRsSsTttuuUvvVWwwxxXyyYzzZ
MultiThreadOne
public class MultiThreadOne extends Thread {
public void run() {
for (char i = 'a'; i <= 'z' ; i++) {
System.out.print(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
MultiThreadTwo
public class MultiThreadTwo implements Runnable {
public void run() {
for (char i = '0'; i <= '9'; i++) {
System.out.print(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// > 다수의 스레드가 run()메소드의 명령을 실행할 경우 같은 객체의 메소드를 호출하여
// 필드값(공유값)을 변경할 경우 잘못된 처리결과 발생 가능
// 해결법) 스레드 동기화를 이용하여 스레드 대한 메소드 호출 제어
// 스레드 동기화 : 스레드에 의헤 메소드 호출시 메소드의 모든 명령을 실행 하기전까지
// 다른 스레드로 메소드를 호출하지 목하도록 방지하는 기능
// > 다른 스레드가 이미 메소드를 호출하여 실행중인 경우 스레드를 일시 중지하여 기존 스레드의
// 메소드 처리가 끝난 후 일시 중지된 스레드가 실행되도록 락(Lock) 기능제공
// 스레드 동기화 처리방법
// 1. synchronized 키워드를 사용하여 메소드 선언 - 동기화 메소드 (Synchronized Method)
// 형식) 접근제한자 synchronized 반환형 메소드명(자료형 매개변수,...) { 명령; ... }
// 2. synchronized 키워드로 블럭을 설정하여 메소드 호출
// 형식) synchronized(객체) { 객체.메소드명(값,...); ... }
// > synchronized 영역의 객체로 호출되는 모든 메소드는 동기화 처리되어 실행
Account
// 은행계좌정보(잔액)를 저장하기 위한 클래스 - 입금 및 출력 관련 메소드 작성
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 void deposit(String name, int amount) {
balance+=amount;
System.out.println("[입금]"+name+"님이 "+amount+"원을 입금하여 잔액은 " + balance + "원입니다.");
}
// 출금 처리 메소드 - 매개변수로 출금자와 출금액을 전달받아 처리
public void withDraw(String name, int amount) {
if(balance < amount) {
System.out.println("[에러]"+name+"님, 잔액이 "+balance+"원 남아 "+amount+"원을 출금할 수 없습니다.");
return;
}
balance -= amount;
System.out.println("[출금]"+name+"님에게 "+amount+"원이 출금되어 잔액은 "+balance+"원입니다.");
}
}
AccountUser
public class AccountUser extends Thread {
private Account account; // 은행계좌정보 - 포함관계
private String userName; // 사용자명
public AccountUser() {
// TODO Auto-generated constructor stub
}
public AccountUser(Account account, String userName) {
super();
this.account = account;
this.userName = userName;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public void run() {
// 프로그램 개발자에 의해 생성된 스레드로 rub() 메소드를 호출하여 명령실행
// > 은행계좌 사용자의 사용하는 은행계좌에 입금 처리하는 메소드 호출
// account.deposit(userName, 5000);
synchronized (account) {
account.withDraw(userName, 5000);
}
}
}
AccountUserApp
public class AccountUserApp {
public static void main(String[] args) {
// Account 클래스로 객체를 생성하여 저장 - 은행계좌 생성
Account account = new Account(10000); // 잔액 10000원
/*
// 단일 스레드 (main)를 이용하여 AccountUser 클래스로 객체를 생성해 저장
// > 은행계좌를 사용하는 사용자를 여러개 생성하여 같은 은행계좌를 사용하도록 설정
AccountUser one = new AccountUser(account, "홍길동");
AccountUser two = new AccountUser(account, "임꺽정");
AccountUser three = new AccountUser(account, "전우치");
// 단일 스레드(main)를 이용하여 모든 은행계좌 사용자를 이용한 은행계좌의 입금 처리
one.getAccount().deposit(one.getUserName(), 5000); // 잔액 : 15000원
two.getAccount().deposit(two.getUserName(), 5000); // 잔액 : 20000원
three.getAccount().deposit(three.getUserName(), 5000); // 잔액 : 25000원
*/
// 스레드를 여러개 생성하여 동시에 입금(출금) 처리
// > 새로운 스레드를 생성하여 run() 메소드의 명령 실행 - 입금처리
new AccountUser(account, "홍길동").start();
new AccountUser(account, "임꺽정").start();
new AccountUser(account, "전우치").start();
}
}
[출금]홍길동님에게 5000원이 출금되어 잔액은 5000원입니다.
[출금]전우치님에게 5000원이 출금되어 잔액은 0원입니다.
[에러]임꺽정님, 잔액이 0원 남아 5000원을 출금할 수 없습니다.
ConsoleCaluelateApp (숙제)
//키보드로 사칙 연산식을 입력받아 연산결과를 계산하여 출력하는 프로그램 작성
//ex) 연산식 입력 >> 20 + 10
// [결과]30
// > 입력 연산식에서 사용 가능한 연산자는 사칙 연산자(*,/,+,-)만 허용
// > 형식에 맞지 않는 연산식이 입력된 경우 에러 메세지 출력 후 프로그램 종료
// > 입력 연산식에 공백 입력이 가능하도록 처리
public class ConsoleCaluelateApp {
public static void main(String[] args) {
}
}