국비학원/공부

24일차 java(12)

mikan- 2023. 7. 3. 13:38

# Thread

// import java.lang.Thread 원래는 써야되지만 java.lang 에 소속된 패키지들은 자동으로 import 처리됨
public class ThreadTest {
	
	// 메인쓰레드 -> 메인메소드를 실행시켜주는 내부적인 쓰레드
	public static void main(String[] args) {
		// 현재 작동중인 쓰레드 객체 Thread.currentThread()
		System.out.println(Thread.currentThread().getName()); // .getname = 쓰레드 이름
		System.out.println(Thread.currentThread().getId()); // .getId = 구분 번호
		
		// 쓰레드 : 실시간으로 데이터전송(채팅), 게임, 실시간 전략
		while (true) { // 무한루프 -> 쓰레드의 한 부분
			System.out.println("main Thread 실행중...");
		}
	}
}

 

# Thread (2)

// 입출력(RandomAccessFile) + Thread
// RandomAccessFile : 특정위치에 접근해서 정해진 파일을 생성해주는 클래스
public class ShareTest implements Runnable{
	
	RandomAccessFile raf = null;
	
	// 2개의 Thread를 생성해서 파일에 특정값을 저장
	public ShareTest() {
		try {
			// 1. 경로 포함해서 생성할 파일명 2. 모드(r,w, rw)
			// rw 가 없으면 생성, 동일한 파일명이 존재하면 덮어씌움
			raf = new RandomAccessFile("c:\\webtest\\readme8.txt", "rw");
			
			// 2. Thread 객체 생성
			Thread t1 = new Thread(this, "lys");
			Thread t2 = new Thread(this, "test");
			
			// 3. Thread 실행
			t1.start();
			t2.start();
			
		} catch (IOException e) {
			System.out.println("파일생성에 오류!!!!!!!!!!!");
			System.out.println("이유는 " + e); // e.toString();
		}
	}
	
	@Override
	public synchronized void run() {
		try {
			for (int i = 0; i < 1000; i++) {
				raf.writeBytes(Thread.currentThread().getName() + "[" + i + "]" + raf.getFilePointer() + "\n");
			}
		} catch (Exception e) {
			System.out.println("파일에 데이터 출력 오류 : " + e);
		}
	}
	
	public static void main(String[] args) {
		
		// 1. Runnable 객체 생성
		ShareTest st = new ShareTest();
		//st.run();
		// 보통은 데이터값을 저장 or 메소드 호출
		// 만약 객체만 호출하고 싶으면
		// new SharTest(); // 익명객체 -> 객체이름만 모름
		
	}
}

 

# Thread (3)

class Test2 {
	String name;
}

// 2. Runnable 인터페이스를 상속받아서 작성 -> run() 기능
public class MyThread extends Test2 implements Runnable {
	
	
	// Thread의 기능을 작성
	@Override
	public void run() {
		
		// 알파벳 찍기
		while (true) { // 아스키코드 65번값 부터 시작
				System.out.println("is Running");
			try {
				Thread.sleep(500); // 1000 -> 1초 동안 멈췄다 실행(500 -> 500ms)
				System.out.println("Thread 이름은 : " + Thread.currentThread().getName());
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
	}
	
	public static void main(String[] args) {

		// 1. Runnable 인터페이스를 상속받은 자식클래스의 객체를 생성
		MyThread mt = new MyThread(); // 부여
		
		// 2. Thread객체를 생성 -> 생성자내부에 매개변수로 자식클래스 객체 전달
		// t.setName("테스트") 도 가능
		Thread t = new Thread(mt, "테스트");

		// 3. start() -> run() 호출
		t.start();
		
	}
}

 

# MultiThread

// 1. Thread를 만드는 방법 (Thread클래스를 상속받아서 작성)
// Thread를 상속받는 이유 = run() 기능 메소드 때문에
public class MultiThread extends Thread {
	
	public MultiThread(String s) {
		super(s); // 부모의 쓰레드 이름을 대신 써주는 생성자 호출
		// this.setName(s); <-> this.getName();
	}
	
	// Thread의 기능을 작성
	@Override
	public void run() {
		
		// 알파벳 찍기
		for (char i = 'A'; i <= 'Z'; i++) { // 아스키코드 65번값 부터 시작
			try {
				Thread.sleep(500); // 1000 -> 1초 동안 멈췄다 실행(500 -> 500ms)
				System.out.println(i);
				System.out.println("Thread 이름은 : " + this.getName());
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
	}
	
	public static void main(String[] args) {
		
		// 1) Thread 클래스의 상속을 받기
		// 2) run() 메소드 재정의 하기
		// 3) Thread 객체 생성
		// 4) 가동
		
		MultiThread mt = new MultiThread("임시"); // 부여
		
		// mt.run() 도 가능하지만 run을 직접적으로 호출하는건 추천 안함
		// 이유는 프로그램의 안정성 때문 -> 안정성을 보장할 수 없다.
		// run = callback method
		// callback method : 운영체제가 내부적으로 불러다 사용하는 메소드
		mt.start();
		
		System.out.println("main쓰레드를 계속 사용할 수 있는지 없는지 판단");
	}

}

 

# MultiThread (2)

import java.io.*;

// 3. Thread의 작성방법(멀티쓰레드 : 한 개 이상의 쓰레드를 실행시키는 것)
public class MultiThread2 {

	public static void main(String[] args) throws IOException {
		
		System.out.println("실행시킬 단을 입력 : ");
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int dan = Integer.parseInt(br.readLine());
		
		// 1. Runnable 객체 생성
		GooGoo gg = new GooGoo(dan);
		
		// 2. Thread 객체 생성 해서 생성자 인수로 gg 전달
		Thread t = new Thread(gg);
		
		// 3. Thread객체 start()호출
		// 2개의 Thread를 동시에 실행하게 되면 서로 경쟁적으로 실행하기 때문에 실행 결과는 섞어져서 나온다.
		// 그래서 우선순위를 정해야된다.
		// 10 > 5 > 1
		PrintThread pt = new PrintThread();
		t.setPriority(10); // Thread.MAX_PRIORITY
		pt.setPriority(Thread.MIN_PRIORITY); // 1
		t.start(); pt.run();
		
		// GooGoo gg = new GooGoo();
		// gg.run();
		
	}
}

// 2. 구구단을 출력 -> Runnable 인터페이스를 상속
class GooGoo implements Runnable {
	
	private int dan;
	
	public GooGoo(int dan) {
		super();
		this.dan = dan;
	}
	
	@Override
	public void run() {
		
		for (int i = 1; i <= 9; i++) {
			try {
				Thread.sleep(1000);
				System.out.println(dan + "단 : " + dan + " * " + i + " = " + dan * i);
			} catch (InterruptedException e) {
				System.out.println(e);
			}
		}
	}
}

// 1. Thread를 직접 상속받아서 작성
class PrintThread extends Thread {
	@Override
	public void run() {
		
		for (int i = 1; i <= 9; i++) {
			try {
				/*
				long sleeptime = (int)(Math.random()*1000+1); // 난수 때문에 0 ~ 999 까지만 떠서 +1 해줘야된다.
				System.out.println(i);
				System.out.println("sleep time : " + sleeptime);
				Thread.sleep(sleeptime);
				*/
				Thread.sleep(1000);
				System.out.println(i);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} // for
	} // run
}

 

# synchronized

public class SingletoneTest {

	public static void main(String[] args) {
		// Singleton ob1 = new Singleton(); // Singleton 이 private로 되어 있어서 그냥은 못가져옴
		Singleton ob1 = Singleton.getInstance();
		Singleton ob2 = Singleton.getInstance();
		Singleton ob3 = Singleton.getInstance();
		
		// 객체명은 3개 지만 실제 객체는 1개이다. -> 주소값 확인
		// 주소값이 하나고 객체명은 다른경우 -> 서로 공유(객체는 하나)
		System.out.println("ob1 : " + ob1 + "\n" + "ob2 : " + ob2 + "\n" + "ob3 : " + ob3);
		
		if (ob1 == ob2) {
			System.out.println("주소값이 같습니다.");
			System.out.println("ob1과 ob2는 같은 객체입니다.(주소가 같다)");
		} else {
			System.out.println("주소값이 다릅니다.");
		}
	}
}



// 클래스 내부에서 특정객체를 한 개 만 생성 = 대여 -> 반납 (메모리 절약목적)
// 스프링 내부에서도 동일한 처리
public class Singleton {

	// 규칙
	// 1. 객체를 한 개 만 생성 -> 공유해서 사용할 수 있도록 -> 정적멤버변수(static)
	private static Singleton instance = null; // 공유객체
	//             Singleton instance = new Singleton();

	// 2. 객체를 생성 -> 자동으로 호출되는 메소드 : 생성자
	//                                   사용목적 : 초기화
	// 형식) private 생성자(){ } = 외부에서 객체생성X
	private Singleton() {
		System.out.println("인스턴스(=객체)");
	}

	// 3. 공유객체를 다른 모든 사람들에게 공유할수 있도록 정적메소드(static)로 제공한다.
	public static Singleton getInstance() {

		// 안 만들어져 있다면 하나생성 해서 요구하는 쪽에 만들어진 객체를 대여한다.
		if (instance == null) {

			// 만들고자 하는 객체를 공유객체로 등록
			// 형식) synchronized(클래스명.class) { 처리 구문; }
			synchronized (Singleton.class) {
				if (instance == null) {
					instance = new Singleton();
				}
			}
		} // outer if
		return instance;
	}
}

 

# synchronized (2)

// 급여통장 (공유데이터) -> ATM(쓰레드) -> 공과금, 보험금, 대출이자...

class ATM implements Runnable {
	private long money = 10000;
	
	@Override
	public void run() {
		
		// 형식1) synchronized(공유할데이터){ 처리해야할 문구; } // DB연동
		synchronized (this) { // this -> ATM객체
			for (int i = 0; i < 5; i++) {
				try {
					Thread.sleep(1000); // 1000ms = 1초간격으로 휴식
				} catch (Exception e) {}
				
				if (getMoney() <= 0) {
					System.out.println("잔액이 부족 합니다. 더이상 출금이 안됩니다.");
					break; // 0원이 있으니 탈출
				}
				withDraw(1000);
			} // for
		} // syn
	}
	
	// 돈을 인출 = 수정
	public void withDraw(long howmuch) {
		
		// 양수인 경우(마이너스가 아닌경우)만 돈을 인출
		if (this.getMoney() > 0) {
			money -= howmuch; // money = money - howmuch
			System.out.println(Thread.currentThread().getName() + ", " + getMoney());
		} else {
			System.out.println("잔액이 부족 합니다.");
		}
	}
	
	// 잔액을 조회 -> 저장된 데이터를 꺼내와서 출력
	// getXXX
	public long getMoney() {
		return this.money;
	}
	
}
public class SyncTest {

	public static void main(String[] args) {
		
		ATM atm = new ATM();
		Thread t1 = new Thread(atm, "보험금"); // Thread 이름
		Thread t2 = new Thread(atm, "공과금");
		t1.start(); t2.start(); // run() -> withDraw()호출
	}
}

 

# Super

import java.util.*;
/*
 * 3. < ? super T > : T(자식클래스)를 고정
 *                   자식클래스와 연관이 있는 모든 부모클래스는 누구나 적용이 되게 하겠다.(매개변수로 전달 받았을때) 
 */

class Person extends Object { // 부모클래스로 사용 할 예정
	
	String name;
	
	//생성자 오버로딩
	Person() {}
	Person(String name) {
		this.name = name;
	}
	
	@Override
		public String toString() {
			
			return this.name;
		}
	
}

// 자식클래스 Man
class Man extends Person {
	
	// String name
	Man(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return this.name;
	}
}


// 자식클래스 Woman
class Woman extends Person {
	
	// String name
	Woman(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return this.name;
	}
}

public class WildSuper {

	public static void main(String[] args) {
		// 1. Man
		List<Man> list = new ArrayList<>();
		
		list.add(new Man("테스트1"));
		list.add(new Man("test2"));
		
		printDate(list);
		System.out.println("===========================");
		
		/*
		// 2. Woman
		List<Woman> list2 = new ArrayList<Woman>();
		list2.add(new Woman("임시2"));
		list2.add(new Woman("임시3"));
		
		printDate(list2);
		System.out.println("===========================");
		
		
		// 3. Person
		List<Person> list3 = new ArrayList<>();
		list3.add(new Person("사장님"));
		list3.add(new Person("이사님"));
		
		printDate(list3);
		System.out.println("===========================");
		
		
		// 4. Double
		List<Double> list4 = new ArrayList<Double>();
		list4.add(12.6);
		list4.add(45.6);
		printDate(list4);
		*/
	}

	// <?> : 매개변수를 전달 받을때 그때 그때 마다 자료형을 바꿔서 전달함
	// 상속관계와 상관없이 모든 클래스가 다 적용이 된다.
	
	// 1. public static void printDate(List<?> list) { // 상속관계 상관없이 모든 클래스 OK
	// <? extends T> Person O man, Woman O Double X
	// 2. public static void printDate(List<? extends Person> list) {
	// 3. ? super T = ?(부모) super T(자식)
	//    ? super Man (?(부모 인 Person 도 가능) (Man은 자식이라 가능 Woman 은 X)
	//    ? super Woman (?(부모 인 Person 도 가능) (Woman은 자식이라 가능, Man 은 X)
	public static void printDate(List<? super Man> list) {
		for (Object obj : list) {
			System.out.println(obj);
		}
	}
	 
	// ?(자식) 대신에 자식클래스명 적으면 안됨
	/*
	public static void printDate(List<? super Person> list) { // 부모상속을 물려받는 자식클래스인 Man, Woman만 가능

		for (Object obj : list) {
			System.out.println(obj);
		}
	}
	*/
}

 

# InetAddress

// InetAddress, Socket, ServerSocket(채팅)
import java.net.*;
// checked Exception계열 -> 반드시 예외처리 해야한다.
// 입출력, DB연동, 네트워크통신, 쓰레드...

public class NetWorkTest {

	public static void main(String[] args) throws Exception {
		InetAddress ia = null; // ip주소정보 에 대한 객체
		InetAddress ia2[]; // 컴퓨터가 한 대 이상일 경우
		
		// www.naver.com(도메인이름) -> ip
		ia = InetAddress.getByName("www.naver.com");
		System.out.println("서버주소 :" + ia.getHostAddress());
		
		// 서버가 한 대 이상 -> getAllByName
		ia2 = InetAddress.getAllByName("www.naver.com");
		
		// 확장 for문
		for (InetAddress aa:ia2) {
			System.out.println("서버들 주소 : " + aa.getHostAddress());
		}
		System.out.println("====자기 컴퓨터의 정보====");
		InetAddress host = InetAddress.getLocalHost();
		System.out.println("컴퓨터 명 : " + host.getHostName());
		System.out.println("ip주소 : " + host.getHostAddress());
			
		
	}
}

'국비학원 > 공부' 카테고리의 다른 글

25일차 java(last) - ChatGUI make  (0) 2023.07.03
25일차 java(13)  (0) 2023.07.03
23일차 java(11)  (0) 2023.07.03
22일차 java(10)  (0) 2023.07.03
21일차 java(9)  (0) 2023.07.03