주말공부 or 복습

주말복습5

동곤일상 2025. 3. 3. 20:21
반응형

1) 입출력 스트림

2)파일입출력스트림

3)보조스트림(BufferedStream)

 

4)ObjectStream

5)SequenceStream

 

6)쓰레드

6-1)쓰레드의 동기화

6-2)Daemon 쓰레드

6-3) 쓰레드 정리

 

7) Function패키지 ( 람다)

 

 


 

1) @ 입출력 스트림 @

 

출력스트림 : 외부로데이터전송

입력스트림 : 외부데이터 읽기

 

 

입출력스트림의 예시를 하나씩만해보자!

 

입력스트림

InputStream은 바이트형(1byte)입력

InputStreamReader : 문자형(1char)입력

public class InputStreamEx2 {
	public static void main(String[] args) throws IOException {
		InputStream is = System.in;
		int data=0;
		while((data=is.read())!= -1) {
			System.out.print((char)data+"");
		}
	}
}
/*
ggg
ggg
안녕하세요
안녕하세요    //InputStream 은 1byte단위로 읽어오므로 문자열이깨짐
*/

/*
InputStreamReader is = new InputStreamReader(System.in); 
로 변경 시
ㅋㅋㅋ
ㅋㅋㅋ
안녕하세요
안녕하세요
*/

 

 

출력스트림

public class Ex {
	public static void main(String[] args) throws IOException {
		OutputStream os = System.out;
		os.write('1');os.write('2');os.write('3');
		os.write('g');os.write('d');os.write('s');
		os.write('가');os.write('니');os.write('다');
		
		os.flush();
		os.close();
	}
}

한글같은경우는 1byte로표현이되지않기에 깨지게 됨

 

public class Ex {
	public static void main(String[] args) throws IOException {
//		OutputStream os = System.out;
		OutputStreamWriter os = new OutputStreamWriter(System.out);
		
		os.write('1');os.write('2');os.write('3');
		os.write('g');os.write('d');os.write('s');
		os.write('가');os.write('니');os.write('다');
		
		os.flush();
		os.close();
	}
}

123gds가니다

 

Writer로 변경시 문자형으로 출력함


2)  @@ 파일입출력스트림 @@

 

public class MyEx {
	public static void main(String[] args) throws IOException {
		FileInputStream fi = new FileInputStream("src\\ex2_outputStream\\Exam1_Writer.java");
		FileOutputStream fo = new FileOutputStream("my2.txt");
		byte[] b = new byte[fi.available()];//fi의 읽기가능한 수
		int data2=0;
		while((data2=fi.read(b))!=-1) {
			fo.write(b);
		}
		fi.close();
		fo.flush();
		fo.close();
		
		Reader r = new FileReader("src/ex2_outputStream/Ex.java");
		FileWriter fw = new FileWriter("my.txt");
		
		char[] c = new char[8000];
		int data=0;
		while((data=r.read(c,0,c.length))!= -1) {
			//c의 0 번인덱스부터 c의 크기까지 읽어라(실제크기리턴)
			fw.write(c);//c(char)을 그대로 write
		}
		fw.flush();
		
		//항상 스트림은 닫아주기
		r.close();
		fw.close();
	}
}

용어들은 모두 같다 (앞에 file이 붙은 게 끝)

FileInputStream :

read() : 1byte단위로 읽어옴

read(byte[] buf) 파일에서 buf크기만큼 읽어 buf에 내용을 저장 후 읽은 수 리턴

 

 

 

FileReader :

read() : 1char단위로 읽음

read(char[] c) 파일에서c크기만큼읽어 c에 내용 저장 후 읽은 수를 리턴

 

 

FileoutputStream :

write(int data) : 1byte단위로 출력

write(byte[] buf) : buf의 내용 출력

 

 

FileWriter :: 

write(int data) : 1char단위로 출력

write(char[] buf) : buf의 내용 출력

 write(String str) : str문자열의 내용을 출력

 


3) @@ 보조스트림 @@

BufferedReader

 

보조스트림이란?

* 1. 기존의 스트림에 새로운기능을 추가

* 2. 객체 생성시 다른 스트림을 생성자의 매개변수로받는다

 

BufferedReader는 한줄씩 읽어온다는 장점이 있음!!!!

public class BufferedReaderEx1 {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		//br : 키보드에서입력된내용을 한줄씩 읽을수있음(readLine())
		System.out.println("저장할 내용을 입력 ( 종료 : ctrl+Z )");
		Writer w = new FileWriter("bufferd.txt");
		String data=null;
		while((data=br.readLine())!= null) {
			System.out.println(data);
			w.write(data+"\n");
		}
		w.flush();w.close();
		br.close();
	}
}

저장할 내용을 입력 ( 종료 : ctrl+Z )

하이

하이

하이루

하이루

bufferd.txt에 저장


4)@@ ObjectStream @@

 

ObjectOutputStream

* 1. 객체를 외부로전송 할 수 있는 스트림

* 2. 외부전송이 가능한 객체는 반드시 Serializable 인터페이스를 구현해야함

* ==> 직렬화

* ==> Serializable 인터페이스를 구현하지않은 객체를 외부전송시

* NotSerializableException발생

 

* 3.ObjectOutputStream으로 전송된객체는 ObjectInputStream객체로읽음

 

class Customer implements Serializable{//꼭 구현!
	private String name;
	private  int age;
	//transient : 직렬화 대상의 객체에서 해당멤버는 제외
	private transient int pw;
	public Customer(String name, int age,int pw) {
		super();
		this.name = name;
		this.age = age;
		this.pw = pw;
	}
	@Override
	public String toString() {
		return name +","+ age +","+pw ;
	}
	
}
//-------------------------------------------------------------------------------------------
public class ObjectOutputSteamEx1 {
	public static void main(String[] args) throws IOException {
		//fos스트림의 목적지 : object.ser
		FileOutputStream fos = new FileOutputStream("object.ser");
		ObjectOutputStream oos = new ObjectOutputStream(fos/*목적지*/);
		Customer c1 = new Customer("하이", 44,9844);
		Customer c2 = new Customer("루", 24,5312);
		System.out.println(c1);
		System.out.println(c2);
		
		oos.writeObject(c1);//c1객체를 object.ser로 전송
		oos.writeObject(c2);//c2객체를 object.ser로 전송
		oos.close();
		fos.close();
	}
}

다음과같이 객체 자체를전송이 가능함.

 

ObjectInputStream(new FileInputStream())으로 읽어오기

public class ObjectInputStreamEx1 {
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		//ois스트림 : object.ser파일에서 객체를  읽을 수 있는 스트림
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.ser"));
		int data=0;
		Customer c1 = (Customer) ois.readObject();//object->Customer로 다운캐스팅
		Customer c2 = (Customer) ois.readObject();//readObject() 메서드의 리턴타입 : Object
		
//		Object c1 =  ois.readObject();
//		Object c2 =  ois.readObject(); 출력은 다운캐스팅을 하나 안하나 똑같음
		System.out.println(c1);
		System.out.println(c2);
	}
}

유동곤,1233,24

김삿갓,643,16

 

 

 


5) Sequence Stream

 

여러개의 스트림을 하나의스트림으로 합침

 

package ex7_other;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.Vector;

public class SequenceStreamEx1 {
	public static void main(String[] args) throws IOException {
		File f = new File("src/sequen");
		String[] files = f.list();
		//꼭 Vector를 사용하자 (ArrayList등을 사용하면 v.elements사용불가)
		//Vector는  Enumeration을 제공
		Vector<InputStream> v = new Vector<InputStream>();
		for(String file : files) {
			File f2 = new File(f,file);
			if(f2.isFile()) {
				v.add(new FileInputStream(f2));//f2파일을 vector에 저장
				}
		}
		//Enumeration v.elements();
		//s :[new FileInputStream("Exam1.java),("FileEx1.java)..... 등
		//  여러개의 스트림을 한개의 스트림으로 연결시켜줌
		SequenceInputStream s =  new SequenceInputStream(v.elements());
		FileOutputStream fos = new FileOutputStream("file예제2.txt");
		int data = 0;
		byte[] buf = new byte[s.available()];//s의 읽기가능한 바이트 수
		while((data=s.read(buf))!= -1) {
			fos.write(buf,0,data);
			//File예제.txt에 내용을 출력해보자
		}
		
		fos.flush();
		fos.close();
		s.close();
	}
}

이 패키지의 하위파일들을 하나의스트림으로합칠것

 

파일의 리스트를 모두 vector안에 넣는다

그 Vector<InputStream>을 

SequenceInputStream에 넣어줘 하나의 Stream으로 합친다.

 

그 후 FileOutputStream로 파일을 만들어 저장

(FileWriter 등으로

 


6) @@ 쓰레드 @@

쓰레드 : 하나의 프로세서에서

여러개의 작업을 하게 만들어줌

 

Runnable의 run()메서드를 사용해

Thread에 넣어줌.,

쓰레드의 이름을 정하지않고 실행 시 Thread-0 과 같이 숫자로 분류해줌

 

하나의쓰레드가 sleep상태에들어가면 다음 쓰레드가 동작을 하게 됨

package ex1_create;

public class Exam1 {
	public static void main(String[] args) {
		System.out.println(Thread.currentThread().getName()+"시작");//main쓰레드
		
		Runnable f; //Runnable은 함수적인터페이스임(추상메서드가 1개)
		//매개변수가없고 리턴값도없음!!
		f=()->{
			for (int i = 0; i < 5; i++) {
				System.out.println(i+":"+Thread.currentThread().getName());
				try {
					Thread.sleep(1000);//대기상태(멀티쓰레드사용을 위해)
				}
				catch(InterruptedException e) {}
			}
		};
		
		Thread t1 = new Thread(f,"하하");
		Thread t2 = new Thread(f);
		t1.start();t2.start();
		System.out.println(Thread.currentThread().getName()+"종료");
	}
}

main시작

main종료

0:Thread-0

0:하하

1:Thread-0

1:하하

2:Thread-0

2:하하

3:하하

3:Thread-0

4:Thread-0

4:하하

 

 


@@ 6-1) 쓰레드의 동기화 @@

 

동기화방법은 크게 2가지가존재

1. 동기화메서드 사용

2. 동기화블럭 사용

 

동기화블럭 사용 예

package ex2_synchronized;

class SyThred extends Thread{

	private static Object Lock = new Object();
	private String name;
	
	public SyThred(String name) {
		super(name);//부모생성자에 이름을 넘김
	}
	@Override
	public void run() {
		synchronized (Lock) {
			
			for (int i = 0; i < 5; i++) {
				System.out.println(i+"::"+Thread.currentThread().getName());
										//현재쓰레드의 이름
			}
		}
	}
}
public class Ex1_block {
	
	public static void main(String[] args) {
		SyThred s1 = new SyThred("하하");
		SyThred s2 = new SyThred("동곤자바");
		s1.start();
		s2.start();
		
	}

}

0::하하

1::하하

2::하하

3::하하

4::하하

0::동곤자바

1::동곤자바

2::동곤자바

3::동곤자바

4::동곤자바


동기화 메서드 사용 예

* 2. 동기화 메서드방식

* 메서드에 synchronized 예약어사용

* (메서드를 lock으로사용함)

* 동기화메서드는유일해야한다.

* 공유객체의 메서드여야한다.

class PrintThread3 extends Thread{
	Printer prt;
	char ch;
	PrintThread3(Printer prt , char ch){
		this.prt = prt;
		this.ch = ch;
	}
	@Override
	public void run() {
		for (int i = 0; i < 5; i++) {
			prt.printChar(ch);
		}
	}
	
}
//------------------------------------------------------------
class Printer{

	public synchronized void printChar(char ch) {//동기화메서드
		for (int i = 0; i < 5; i++) {
			System.out.print(ch);
		}System.out.println();
	}	
}

public class PrintThreadEx3 {
	public static void main(String[] args) {
		Printer p = new Printer();
		PrintThread3 t1 = new PrintThread3(p, 'A');
		PrintThread3 t2 = new PrintThread3(p, 'B');
		PrintThread3 t3 = new PrintThread3(p, 'C');
		t1.start();t2.start();t3.start();
	}
}

AAAAA

AAAAA

AAAAA

AAAAA

AAAAA

CCCCC

CCCCC

CCCCC

CCCCC

CCCCC

BBBBB

BBBBB

BBBBB

BBBBB

BBBBB


6-2) Daemon 쓰레드


데몬 스레드
 * 1.일반스레드의 보조기능담당
 * 2.일반스레드가 종료되면 데몬스레드도 종료
 * 3.가비지콜렉터가 대표적인 데몬스레드
 * 4.무한반복형태로구현

 

setDaemon(true) 로 데몬쓰레드설정을 해줌

package ex4_daemon;

class DaemonThread extends Thread {
	
 public DaemonThread(String name) {
	 super(name); 
	 }
	 
	@Override
	public void run() {
		int i =1;
		while (true) {
			
			System.out.println(i++ +":"+Thread.currentThread().getName());
			try {
				sleep(100);//sleep 상태 동안 다른쓰레드 실행
			} catch (InterruptedException e) {
			}
		}
		// run()의 while문은 break문없이
		// 무한으로 this를 출력한다
	}
}

//----------------------------------------------------------------------------
public class DaemonEx1 {
	public static void main(String[] args) throws InterruptedException {
		System.out.println(Thread.currentThread().getName() + "스레드 시작");
		DaemonThread t1 = new DaemonThread("쓰레드1");
		DaemonThread t2 = new DaemonThread("쓰레드2");
		t1.setDaemon(true);
		t2.setDaemon(true);// 데몬스레드로지정
		t1.start();
		t2.start();
		Thread.sleep(1000);// mainThread를 1초간 sleep 후 종료 --> DaemonThread도 종료

		System.out.println(Thread.currentThread().getName() + "스레드 종료");
	}
}

main스레드 시작

1:쓰레드1

1:쓰레드2

2:쓰레드1

2:쓰레드2

3:쓰레드1

3:쓰레드2

4:쓰레드1

4:쓰레드2

5:쓰레드2

5:쓰레드1

6:쓰레드2

6:쓰레드1

7:쓰레드2

7:쓰레드1

8:쓰레드2

8:쓰레드1

9:쓰레드2

9:쓰레드1

10:쓰레드1

10:쓰레드2

main스레드 종료

 

이론상 Thread는 무한으로 실행될것같다.

하지만 메인Thread(Main)이 종료되면 종료된다

main을 1초정도 sleep을 해뒀는데

그 동안만 실행되고 종료되는것임.


6-3)  쓰레드 정리

* 쓰레드정리
 * 1.스레드 생성
 *   1) Thread 클래스상속 , run메서드 오버라이딩
 *   2) Runnable 인터페이스구현 , run메서드오버라이딩 , Thread객체에 주입
 *  
 *  2.스레드상태
 *    Thread 생성상태 : new Thread();
 *    Runnable 상태 : start()메서드 실행 후
 *    Running 상태 : start()에 의해 run()메서드가 실행중인 상태
 *    
 *    대기상태 : sleep(), 동기화 lock획득실패,
 *            wait() : notify() or notifyAll로 꺠우지않으면 무한대기
 *            			대기상태해제시 Runnable상태로 변경
 *   Dead 상태 : run메서드를 모두 실행하고 종료된 상태
 *   
 * 3.주요메서드
 *  (1) start() : 병렬화 기능 , run메서드 호출 , new 상태-->Runnable상태
 *  (2) run()  : 쓰레드의기능 , 스레드가 실행하는 메서드.
 *  (3) sleep(ms) : 밀리초만큼 대기
 *  (4) setDaemon(boolean) : true인경우 DaemonThread로 사용하곘단소리
 *  			(start전에 실행)	Daemon스레드 :일반 스레드종료시 함께종료
 *  (5) join() : 해당스레드가 종료시까지 호출한메서드가 대기
 *  (6) setPriority(1~10) : 우선순위설정
 *  (7) interrupt() : InterruptedException발생시킴
 *  (8) stop()메서드는 쓰지마라.
 *  
 *  4.동기화 : Synchronized 예약어사용
 *  동기화블럭 : lock설정 ,  공유객체로 lock설정해야함
 *  동기화메서드 :공유객체의 메서드여야함(유일해야함)
 *  		메서드자체가 동기화영역 
 *  
 *  5.wait , notify , notifyAll
 *  Object 멤버
 *  동기화영역에서만 사용 가능

7) @@ Function 패키지 @@

 

7-1) Consumer 인터페이스

 

consumer인터페이스는 매개변수가있으며 리턴값이 없음

 

accept를 통해 구현한 인터페이스를 사용가능함!!

예제로 보여주겠음

 

package ex1_conumer;

import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.ObjIntConsumer;

public class MyEx {
	public static void main(String[] args) {
		Consumer<String> f1= (t)->System.out.println(t+" !!출력!!");
		f1.accept("하하");
		
		BiConsumer<String, Integer> f2 = (s,i)->System.out.println(s+"는"+i+"살");
		f2.accept("유동곤", 26);
		
		DoubleConsumer f3 = (s)->System.out.printf(s+" + 20 : %.3f \n",(s+20));
		f3.accept(10.56);
		
		IntConsumer f4 = (s)->{
			int sum=0;
			for (int j = 1; j <= s; j++) {
				sum+=j;
			}System.out.println("1부터"+s+"의 합 : "+sum);};
		f4.accept(10);
		
		ObjIntConsumer<String> f5 = (s,i)->{System.out.println(s+"는 "+i+"번째 손님");};
		f5.accept("하하", 10);
	}
}

하하 !!출력!!

유동곤는26살

10.56 + 20 : 30.560

1부터10의 합 : 55

하하는 10번째 손님

 

 

 


7-2) Suplier 인터페이스

 

T getXXX()  : 매개변수가없으며 리턴값이 존재

 

* Supplier<T> : T get()

* IntSupplier : int getAsInt()

* DoubleSupplier : double getAsDouble()

* BooleanSupplier : boolean getAsBoolean()

package ex2_Supplier;

import java.util.Iterator;
import java.util.function.IntSupplier;
import java.util.function.Supplier;

public class Myex {

	public static void main(String[] args) {
		Supplier<String> s =()->"java";
		System.out.println(s.get());
		
		IntSupplier s2 = ()->{
			System.out.println("@@1부터100까지의합@@");
			int sum=0;
			for (int i = 0; i <= 100; i++) {
				sum+=i;
				}
			return sum;
			};
		System.out.println(s2.getAsInt());

	}
}

java

@@1부터100까지의합@@

5050