package Week02.day0719;
import java.sql.Date;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
class Car{
private String model; // 모델명
private int effciency; // 연비 (cc)
private int distance; // 뛴거리 (km)
private HashMap fixHis = new HashMap(); // 수리이력
private String nowOwner;
private HashSet accidentHis = new HashSet(); // 사고이력
Car(String model, int effciency, int distance, String nowOwner){
this.model = model;
this.effciency = effciency;
this.distance = distance;
this.nowOwner = nowOwner;
}
public void addAccidentHis() throws Exception { // 사고이력을 추가한다. HashMap
// - info: location(장소), date(20190102), time(12:50)이 / 를 구분자로 add
//구분자 쓰는법 : String data[] = info.split("/");
// ex. format : " 로타리사거리/20190501/14:00 "
// - 조건1: 같은 사고이력을 추가할 수 없다
// - 조건2: 잘못된 날짜와 시간이 추가되면 안된다(ex. 55시. 55월...)
AccidentHis in = new AccidentHis("로타리사거리", "20190228", "12:00");
//같은 사고이력 체크 , hashset은 중복체크 스스로 하므로 필요가 없다.
if(accidentHis.contains(in)) {
throw new Exception("같은 사고이력을 추가하실 수 없습니다.");
}
//잘못된 날짜와 시간 추가 방지 체크
if(Util.validationDate(in.getDate() + " " + in.getTime()))
accidentHis.add(in);
else
throw new Exception("잘못된 날짜이거나 잘못된 시간 형식입니다.");
}
public void printAccidnetHis() throws ParseException{ // 사고이력을 출력한다. HashMap
// 형식: ‘{0} - {1} ? {2}’, {0}: 장소, {1}: 날자, {2}: 시간
// 날자는 xxxx.xx.xx Format으로 출력한다
SimpleDateFormat original_format = new SimpleDateFormat("yyyyMMdd");
SimpleDateFormat new_format = new SimpleDateFormat("yyyy.MM.dd");
Iterator it = accidentHis.iterator();
while(it.hasNext()) { // hasnext를 쓰면 아래 에선 쓰지 못하므로 변수를 써서 한다.
AccidentHis e = (AccidentHis) it.next();
java.util.Date original_date = original_format.parse(e.getDate());
String new_date = new_format.format(original_date);
String msg = "{0} - {1} ? {2}";
Object[] arguments = {((AccidentHis)e).getLocation(), new_date, ((AccidentHis)e).getTime()};
String result = MessageFormat.format(msg, arguments);
System.out.println(result);
}
}
//SubString으로 활용하는 방법도 있다.
// public boolean DateCheck(int month, int date, int hour, int min) {
// if(month>0 && month<=12)
// if(date>0 && date<=31)
// if(hour>=0 && hour <24)
// if(min>=0 && min<60)
// return true;
// return false;
// }
// public void addAccidentHis(String info) {
// String[]ac = info.split("/");
// int month = (Integer.parseInt(ac[1].substring(4, 6)));
// int date = (Integer.parseInt(ac[1].substring(6, 8)));
// int hour = (Integer.parseInt(ac[2].substring(0, 2)));
// int min = (Integer.parseInt(ac[2].substring(3, 5)));
// Accident acc = new Accident(ac[0],ac[1],ac[2]);
// if(!DateCheck(month, date, hour, min)) {
// System.out.println("��¥/�ð��� �߸� �Է��߽��ϴ�.");
// }else {
// accidentHis.add(acc);
// }
// }
public void addFixHis(String date, String item, String fixcmt) throws Exception { // 수리이력을 추가한다. item : 수리부품 , HashMap
// - date별 item(수리부품)의 fixcmt(수리이력)을 추가한다
// - 조건1 : date별 item(수리부품)은 중복될 수 없다(같은날 같은 엔진)
FixHis fh = new FixHis(date, item, fixcmt);
String strKey = date + "/" + item;
//System.out.println(strKey); //20190717/범퍼
String strFixinfo = date + "/" + item + "/" + fixcmt;
if(fixHis.containsKey(strKey)) {
throw new Exception("같은 수리부품은 중복 될 수 없습니다.");
}
else{
fixHis.put(strKey, strFixinfo);
}
}
public void printFixHis() { // 수리이력을 출력한다. HashMap
// - 날자 ? 부분 ? 수리Cmt를 출력한다
Set set = fixHis.entrySet(); // HashMap에 넣은 Key와 Value를 Set에 넣고 iterator에 값으로 Set정보를 담에 준다.
Iterator it = set.iterator();
while(it.hasNext()) {
Entry e = (Entry) it.next(); // Entry 객체를 이용하면 key 와 value를 동시에 구할 수 있다
System.out.println(e.getValue()); // values() --> 저장된 모든 값 출력
}
}
}
class Util{
public static boolean validationDate(String date) {
//setLenient(boolean lenient) :날짜가 파싱될 때 허술하게 할지말지를 설정.
//이렇게 체크할 경우, 유효한 날짜가 아니면 ParseException을 던질것이고, 유효한 날짜라면 true로 반환.
try {
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMdd HH:mm");
dateformat.setLenient(false);
dateformat.parse(date);
return true;
}catch(ParseException e) {
return false;
}
}
}
class AccidentHis{
String location;
String date;
String time;
AccidentHis(String location, String date, String time){
this.location = location;
this.date = date;
this.time = time;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public int hashCode() {
return Objects.hash(location, date, time);
}
public boolean equals(Object obj) {
if (obj != null && obj instanceof AccidentHis) { // obj가 AccidentHis의 Instance
return location.equals(((AccidentHis) obj).location) && date.equals(((AccidentHis) obj).date) && time.equals(((AccidentHis) obj).time); // 값이 같은지 비교
} else {
return false;
}
}
}
class FixHis{
String date;
String item;
String fixcmt;
FixHis(String date, String item, String fixcmt){
this.date = date;
this.item = item;
this.fixcmt = fixcmt;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public String getFixcmt() {
return fixcmt;
}
public void setFixcmt(String fixcmt) {
this.fixcmt = fixcmt;
}
public boolean equals(Object obj) {
if (obj != null && obj instanceof FixHis) {
String thisTmp = date + "/" + item;
String tmp = ((FixHis)obj).getDate() + "/" + ((FixHis)obj).getItem();
return thisTmp.equals(tmp);
}
else return false;
}
public int hashCode() {
return Objects.hash(date, item, fixcmt);
}
}
public class 실습9일차 {
public static void main(String[] args) throws Exception {
Car car = new Car("말리부", 3000, 10000, "홍길동");
car.addAccidentHis();
try {
car.addAccidentHis(); // 오류메세지 출력용
}catch (Exception e) {
e.printStackTrace();
}
car.printAccidnetHis();
car.addFixHis("20190719", "와이퍼", "교체");
car.printFixHis();
try {
car.addFixHis("20190719", "와이퍼", "교체"); // 오류메세지 출력용
}catch (Exception e) {
e.printStackTrace();
}
}
}
--------------------------------------------------------------------------
package Week02.day0719;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
class Plane{
private String model;
private String airline; //항공사이름
private HashSet fixHis1 = new HashSet(); // 수리이력
Plane(String model, String airline){
this.model = model;
this.airline = airline;
}
public void addFixHis(String info) throws Exception { // 수리이력을 추가한다 - 같은 수리이력을 추가할 수 없다(airport/date/cmt)
String data[] = info.split("/");
try {
FixHis1 ac = new FixHis1(data[0], data[1], data[2]);
if(fixHis1.contains(ac))
throw new Exception("같은 수리이력은 추가 될 수 없습니다.");
else
fixHis1.add(ac);
} catch(Exception e) {
e.printStackTrace();
}
}
public void printFixtHis() { // 수리이력을 출력한다. - - 수리이력을 출력: 공항-날자-사고내용
Iterator it = fixHis1.iterator();
while(it.hasNext()) {
FixHis1 e = (FixHis1) it.next();
System.out.println(e.getAirport() +"-"+ e.getDate() +"-"+ e.getCmt());
}
}
}
class FixHis1{ //set은 hashcode와 equals를 재정의해야함.
private String airport; // 공항
private String date; // 수리일자
private String cmt; // 수리내용
FixHis1(String airport, String date, String cmt){
this.airport = airport;
this.date = date;
this.cmt = cmt;
}
public String getAirport() {
return airport;
}
public void setAirport(String airport) {
this.airport = airport;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getCmt() {
return cmt;
}
public void setCmt(String cmt) {
this.cmt = cmt;
}
public boolean equals(Object obj) {
if (obj != null && obj instanceof FixHis1) {
String thisTmp = airport + date + cmt;
String tmp = ((FixHis1) obj).getAirport() + ((FixHis1) obj).getDate() + ((FixHis1) obj).getCmt();
return thisTmp.equals(tmp);
} else
return false;
}
public int hashCode() { // 추가할수록 값이 디테일하게 쪼개짐.
return Objects.hash(airport, date, cmt);
}
}
public class 실습9일차2번 {
public static void main(String[] args) {
Plane pl = new Plane("보잉707", "아시아나");
try {
pl.addFixHis("인천공항/20190701/타이어교체");
pl.addFixHis("나하공항/20190601/날개교체");
pl.addFixHis("인천공항/20190701/타이어교체");
pl.printFixtHis();
} catch(Exception e) {
e.printStackTrace();
}
}
}
--------------------------------------------------------------------------
package Week02.day0719;
public class ThreadEx1 {
public static void main(String[] args) {
//싱글 스레드
long startTime = System.currentTimeMillis();
for(int i=0; i<500; i++)
System.out.printf("%s", new String("-"));
System.out.print("소요시간1:" + (System.currentTimeMillis()-startTime)); // 소요시간1:32
for(int i=0; i<500; i++)
System.out.printf("%s", new String("|"));
System.out.print("소요시간2:" + (System.currentTimeMillis()-startTime)); // 소요시간2:43
}
}
--------------------------------------------------------------------------
/* Multi Threading */
1. 여러 Thread가 하나의 자원을 공유
2. Monitors
- Monitor란 상태변수
- Monitors는 일종의 열쇠, 임계영역(critical section)을 들어가기 위해선 이 열쇠가 필요하다.
- 임계영역을 만들기 위해 synchronized 키워드를 사용한다.
package Week02.day0719;
public class ThreadEx2 {
static long startTime = 0;
public static void main(String[] args) {
//멀티스레드
ThreadEx2_1 th1 = new ThreadEx2_1();
th1.run();
startTime = System.currentTimeMillis();
for(int i=0; i<300; i++) {
System.out.print("-");
}
System.out.print("소요시간2:" + (System.currentTimeMillis()- ThreadEx2.startTime)); // 소요시간2:2
}
}
class ThreadEx2_1 extends ThreadEx2{
public void run() {
for(int i=0; i<300; i++) {
System.out.print("|");
}
System.out.print("소요시간2:" + (System.currentTimeMillis()- ThreadEx2.startTime)); // 소요시간2:1563517789948
}
}
--------------------------------------------------------------------------
package Week02.day0719;
public class ThreadSwtiching {
public static void main(String[] args) {
//ThreadSwtiching 예제
/*앞에서 만든 쓰레드 B를 만든 후 Start
* 해당 쓰레드가 실행되면, 해당 쓰레드는 run메소드안에서 자신의 모니터링 락을 획득
*/
ThreadB b = new ThreadB();
b.start();
//b에 대하여 동기화 블럭을 설정
//만약 main 쓰레드가 wait을 하게 되면서 main쓰레드 대기
synchronized(b) { // synchronized{} : 동기화 처리부분
try {
//b.wait()메소드를 호출.
//메인쓰레드는 정지
//ThreadB가 5번 값을 더한 후 norify를 호출하게 되면 wait에서 깨어남
System.out.println("b가 완료될 때까지 기다립니다.");
b.wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
//깨어난 후 결과를 출력
System.out.println("Total is : " + b.total);
}
}
}
class ThreadB extends Thread{
/*해당 쓰레드가 실행되면 자기 자신의 모니터링 락을 획득
* 5번 반복하면서 0.5초씩 쉬면서 total에 값을 누적
* 그 후에 notify()메소드를 호출하여 wait하고 있는 쓰레드를 깨움
*/
int total;
public void run() {
synchronized(this) {
for(int i=0; i<5; i++) {
System.out.println(i + "를 더합니다.");
total+=i;
try {
Thread.sleep(500);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
}
//출력값
//b가 완료될 때까지 기다립니다.
//0를 더합니다.
//1를 더합니다.
//2를 더합니다.
//3를 더합니다.
//4를 더합니다.
//Total is : 10
--------------------------------------------------------------------------
package Week02.day0719;
public class SyncThread {
public static void main(String[] args) {
//동기화 적용예제
User user = new User();
//3개의 스레드 객체 생성
UserThread p1 = new UserThread(user, "A1");
UserThread p2 = new UserThread(user, "B2");
UserThread p3 = new UserThread(user, "C3");
//스레드 스케줄링 : 우선순위 부여
p1.setPriority(p1.MAX_PRIORITY);
p2.setPriority(p3.NORM_PRIORITY);
p3.setPriority(p3.MIN_PRIORITY);
System.out.println("----------------------");
System.out.println("sychronized 적용안한 경우");
System.out.println("----------------------");
//스레드 시작
p1.start();
p2.start();
p3.start();
}
}
//Heap영역의 멤버 변수는 공통으로 사용
class User{
private int userNo = 0;
//임계 영역을 지정하는 sychronized메소드
public void add(String name) {
System.out.println(name + ":" + userNo++ + "번째 사용"); // sychronized 가 없으므로, 랜덤값이 출력됨.
}
}
class UserThread extends Thread{
User user;
UserThread(User user, String name){
super(name);
this.user = user;
}
public void run() {
try {
for(int i=0; i<3; i++) {
user.add(getName());
sleep(500);
}
}catch(InterruptedException e) {
System.err.println(e.getMessage());
}
}
}
//출력값
//----------------------
//sychronized 적용안한 경우
//----------------------
//A1:0번째 사용
//B2:1번째 사용
//C3:2번째 사용
//A1:3번째 사용
//C3:3번째 사용
//B2:3번째 사용
//A1:4번째 사용
//C3:5번째 사용
//B2:4번째 사용
--------------------------------------------------------------------------
package Week02.day0719;
public class SyncThread2 {
public static void main(String[] args) {
//동기화 적용예제
User2 user = new User2();
//3개의 스레드 객체 생성
UserThread2 p1 = new UserThread2(user, "A1");
UserThread2 p2 = new UserThread2(user, "B2");
UserThread2 p3 = new UserThread2(user, "C3");
//스레드 스케줄링 : 우선순위 부여
p1.setPriority(p1.MAX_PRIORITY);
p2.setPriority(p3.NORM_PRIORITY);
p3.setPriority(p3.MIN_PRIORITY);
System.out.println("----------------------");
System.out.println("sychronized 적용한 경우");
System.out.println("----------------------");
//스레드 시작
p1.start();
p2.start();
p3.start();
}
}
//Heap영역의 멤버 변수는 공통으로 사용
class User2{
private int userNo = 0;
//임계 영역을 지정하는 sychronized메소드
//메소드 내 작업이 완료될 때까지 다른 Thread가 들어올 수 없다.
public synchronized void add(String name) {
System.out.println(name + ":" + userNo++ + "번째 사용");
}
}
class UserThread2 extends Thread{
User2 user;
UserThread2(User2 user, String name){
super(name);
this.user = user;
}
public void run() {
try {
for(int i=0; i<3; i++) {
user.add(getName());
sleep(500);
}
}catch(InterruptedException e) {
System.err.println(e.getMessage());
}
}
}
//출력값
//----------------------
//sychronized 적용한 경우
//----------------------
//A1:0번째 사용
//B2:1번째 사용
//C3:2번째 사용
//B2:3번째 사용
//A1:4번째 사용
//C3:5번째 사용
//B2:6번째 사용
//C3:7번째 사용
//A1:8번째 사용
'Java' 카테고리의 다른 글
객체 정렬하기 (0) | 2019.07.23 |
---|---|
Java - Stream(byte, 문자) (0) | 2019.07.22 |
Java - 제네릭스, Wildcard, 열거형, Thread (0) | 2019.07.18 |
Java - ArrayList, LinkedList, Stack, Queue, Iterator, ListIterator, Comparator, HashSet, TreeSet, HashMap, Set (0) | 2019.07.17 |
Java - Format, java.sql.date, StringTokenizer, Calendar, Class, Reflection (0) | 2019.07.16 |