본문 바로가기
개발 공부 Today I Learned

[국비 30일차 TIL] 스레드, 중첩 클래스, 입출력 스트림,

by 개발자신입 2024. 1. 3.
반응형

 

Queue

자바에서 Queue는 데이터를 저장하는 자료 구조 중 하나입니다. 큐는 일반적으로 "선입선출" (FIFO) 원칙에 따라 동작하며, 먼저 들어온 데이터가 먼저 나가게 됩니다. 큐는 주로 대기열 관리, 작업 스케줄링, 이벤트 처리 등 다양한 상황에서 사용됩니다.

자바에서는 java.util.Queue 인터페이스를 제공하여 다양한 큐 구현체를 사용할 수 있습니다. 몇 가지 주요 메서드로는 enqueue (또는 offer), dequeue (또는 poll), peek 등이 있습니다. 대표적인 구현체로는 LinkedList나 ArrayDeque가 있습니다.

 

package com.coffee.coll;

import java.util.LinkedList;
import java.util.Queue;

class Message {
	public String command;
	public String to;
	
	public Message(String command, String to) {
		this.command = command;
		this.to = to;
		
	}
}


public class Queue01 {

	public static void main(String[] args) {
//		Queue<Integer> queue = new LinkedList<Integer>();
		Queue<Message> messageQueue = new LinkedList<Message>();
		
		messageQueue.offer(new Message("sendMail", "홍길동"));
		messageQueue.offer(new Message("sendSMS", "김길동"));
		messageQueue.offer(new Message("sendKatalk", "이길동"));
		
		while(!messageQueue.isEmpty()) {
			Message msg = messageQueue.poll();
			System.out.println(msg.command + " : " + msg.to);
		}
	}

}

 

stack

자바에서 스택(Stack)은 데이터를 저장하는 자료 구조 중 하나로, "후입선출" (LIFO) 원칙에 따라 동작합니다. 스택은 가장 나중에 추가된 데이터가 가장 먼저 제거되는 구조를 가지고 있습니다.

자바에서는 java.util.Stack 클래스를 사용하여 스택을 구현할 수 있습니다. 이 클래스는 Vector를 확장하고, 스택의 기본 동작을 제공합니다.

주요 메서드로는 push (데이터 추가), pop (데이터 제거), peek (맨 위의 데이터 조회) 등이 있습니다.

package com.coffee.coll;

import java.util.Stack;

/*
 *  선입선출 First In First Out 
 *  후입선출 Last In First Out (나중에 넣은 객체가 먼저 빠져나가는 구조)
 */

class Coin {
	private int value;
	
	public Coin(int value) {
		this.value = value;
	}
	public int getValue() {
		return value;
	}
}

public class Stack01 {
	public static void main(String[] args) {
		Stack<Coin> coinBox = new Stack<Coin>();
		
		coinBox.push(new Coin(100));
		coinBox.push(new Coin(50));
		coinBox.push(new Coin(500));
		coinBox.push(new Coin(10));
		
		while (!coinBox.isEmpty()) {
			Coin coin = coinBox.pop();
			System.out.println("꺼내온 동전 : " + coin.getValue());
			
			
		}
		
	}

}

 

 

Thread

01

 

 프로세스
 운영체제에서는 실행중인 하나의 어플리케이션을 프로세스라 부름.
 사용자가 어플리케이션을 실행하면 운영체제로부터 실행에 필요한 메모리를 할당받아 어플리케이션의 코드를 실행하는 것

 스레드
 운영체제는 두 가지 이상의 작업을 동시에 처리하는 멀티 테스킹을 할 수 있도록 CPU 및 메모리 자원을 프로세스마다 적절히 할당해주고, 병렬로 실행시킴.

 프로세스에서 실행 제어만 분리한 실행 단위로, 프로세스보다 가볍고 독립적으로 수행되는 흐름의 단위
 동시에 여러 작업을 처리하기 위해 사용되는 실행 단위

 스레드 생성과 실행
 1. 구현 : Runnable 인터페이스를 구현하는 방법
 2. 확장 : Thread 클래스를 상속받는 방법

 -> 다른 클래스가 상속 중이라면 Thread 클래스를 상속받지 못함.
 이런 때를 대비해서 인터페이스 Runnable이 만들어져 있음.  (but, Thread 클래스를 상속해서 제작하는 것이 편함)

 void run() : 실행코드가 작성되는 메소드
 void start() : 스레드가 시작되도록 요청

 

package com.coffee.thread;

public class ThreadEx extends Thread {
	@Override
		public void run() {
//			super.run();
		System.out.println("Thread 시작");
		}

	public static void main(String[] args) {
		ThreadEx th01 = new ThreadEx();
		th01.start();
	}

}

 

Thread 02

 

package com.coffee.thread;

public class Thread02 extends Thread {
		int seq;
		
		public Thread02(int seq) {
			this.seq = seq;
		}
		
		@Override
		public void run() {
			System.out.println(this.seq + " 스레드 시작");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(this.seq + " 스레드 끝");
		}
		
		
		public static void main(String[] args) {
			System.out.println("main 메소드 시작");
			
			for (int i = 0; i < 10; i++) {
				Thread02 th02 = new Thread02(i);
				th02.start();
				
			}
			System.out.println("main 메소드 끝");
			
	}
}

 

 

Thread 03

 

package com.coffee.thread;

import java.util.ArrayList;
import java.util.List;

public class Thread03 extends Thread {
	int seq;
	
	public Thread03(int seq) {
		this.seq = seq;
	}

	@Override
	public void run() {
		System.out.println(this.seq + " 스레드 시작");
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println(this.seq + " 스레드 끝");
	}
	
	public static void main(String[] args) {
		System.out.println("main 시작");
		List<Thread> tList = new ArrayList<Thread>();
		
		for (int i = 0; i < 10; i++) {
			Thread th1 = new Thread03(i);
			th1.start();
			tList.add(th1);
		}
		
		for (int i = 0; i < tList.size(); i++) {
			Thread t = tList.get(i);
			
			try {
				t.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("main 끝");
	}
}

 

 

Thread 04

 

package com.coffee.thread;

import java.util.ArrayList;
import java.util.List;

class A {
	
}

public class Thread04 extends A implements Runnable {
	int seq;
	
	public Thread04(int seq) {
		this.seq = seq;
	}
	
	@Override
	public void run() {
		System.out.println(this.seq + " 스레드 시작");
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println(this.seq + " 스레드 끝");
	}

	public static void main(String[] args) {
		List<Thread> tList = new ArrayList<Thread>();
		
		for (int i = 0; i < 10; i++) {
			Thread t = new Thread(new Thread04(i));
			// t의 생성자로 Runnable을 구현한 객체를 넘긴 모습
			
			t.start();
			tList.add(t);
		}
		
		for (int i = 0; i < tList.size(); i++) {
			Thread t = tList.get(i);
			
			try {
				t.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("메인 메소드 끝");
	}
}

 

 

입출력 스트림

자바에서의 입출력(I/O) 시스템은 데이터를 읽어오거나 출력하는 기능을 제공하는 부분을 의미합니다. Java I/O는 다양한 소스 및 대상에서 데이터를 읽고 쓸 수 있는 풍부한 API를 제공합니다. 주요 클래스들은 java.io 패키지에 속해 있습니다.

  • InputStream 및 OutputStream : 바이트 기반의 데이터를 읽고 쓰기 위한 추상 클래스입니다. FileInputStream, FileOutputStream, ByteArrayInputStream, ByteArrayOutputStream 등이 이에 해당합니다.
  • Reader 및 Writer : 문자 기반의 데이터를 읽고 쓰기 위한 추상 클래스입니다. FileReader, FileWriter, BufferedReader, BufferedWriter 등이 여기에 속합니다.
  • File 클래스 : 파일 시스템에서 파일 및 디렉토리 정보를 얻거나 조작하기 위한 클래스입니다.
  • Scanner 클래스 : 간단한 키보드 입력을 읽기 위한 클래스로, 사용자로부터 데이터를 쉽게 읽어올 수 있습니다.
  • Console 클래스 : 콘솔에서 입력 및 출력을 다루기 위한 클래스로, 비밀번호 입력 등에 사용될 수 있습니다.

 

package com.coffee.io;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

// Input Output

public class Io01 {
	public static void main(String[] args) throws IOException {
		
		OutputStream os = new FileOutputStream("c:/temp/test.txt");
		byte a = 65;
		byte b = 67;
		byte c = 68;
		
		os.write(a);
		os.write(b);
		os.write(c); // 1byte씩 출력
		
		os.flush();	// 출력 버퍼에 잔류하는 모든 바이트 출력
		os.close();	// 출력 스트림 닫음
	}

}
package com.coffee.io;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;


public class Io02 {
	public static void main(String[] args) throws IOException {
		
		OutputStream os = new FileOutputStream("c:/temp/test2.txt");

		byte arr[] = new byte[] {65,69,72,72,79};
		// 1byte = bit
		
		os.write(arr, 1, 3);
		
		os.flush();	// 출력 버퍼에 잔류하는 모든 바이트 출력
		os.close();	// 출력 스트림 닫음
	}

}
package com.coffee.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;


public class Io03 {
	public static void main(String[] args) throws Exception {
		
		InputStream is = new FileInputStream("c:/temp/test.txt");
		
		while (true) {
			int data = is.read();
			if(data == -1) {
				break;
			}
			System.out.println((char)data); // A C D
		}
		is.close();
	}

}
package com.coffee.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.util.Arrays;


public class Io04 {
	public static void main(String[] args) throws Exception {
		
		InputStream is = new FileInputStream("c:/temp/test.txt");
		
		byte arr[] = new byte[2];
		
		while(true) {
			int readByteNum = is.read(arr);
			if(readByteNum == -1) {
				break;
			}
			for (int i = 0; i < readByteNum; i++) {
				System.out.print((char) arr[i]);
			}
//			System.out.println(readByteNum + " : " + Arrays.toString(arr));
		
		}
		is.close();
	}

}
package com.coffee.io;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

public class Io05 {
	public static void main(String[] args) throws Exception {
		FileOutputStream fos = new FileOutputStream("c:/temp/test.txt");
		Writer writer = new OutputStreamWriter(fos);
		
		writer.write("문자열 저장"); // test.txt 파일에 저장되는 문장
		writer.flush();
		writer.close();
	}

}
package com.coffee.io;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

// 파일 클래스를 이용한 파일 및 폴더 정보 출력

public class Io06 {
	public static void main(String[] args) {
		
		File dir = new File("c:/temp/images"); // 폴더 만들기
		
		if (dir.exists() == false) {
			dir.mkdir(); // mkdir에 s를 붙이면 없는 폴더 전부 만들어줌.
		}
		
		File temp = new File("c:/temp");
		File contents[] = temp.listFiles(); // temp 폴더 안에 있는 파일 리스트 불러오기
		
		System.out.println("시간\t\t\t형태\t\t크기\t이름");
		System.out.println("===========================================================");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd a HH:MM");
		for (File file : contents) {
			System.out.print(sdf.format(new Date(file.lastModified())));
			if(file.isDirectory()) {
				System.out.print("\t<DIR>\t\t\t" + file.getName());
			} else {
				System.out.print("\t\t\t" + file.length()+"\t"+file.getName());
				
			}
			System.out.println("");
		}
	}

}

 

 

 중첩 클래스


 < 내부 클래스 (Inner Class) >

 클래스 내부에 선언된 클래스 = 두 클래스가 서로 긴밀한 관계에 있음


 장점

  •  내부 클래스에서 외부 클래스의 멤버들에 쉽게 접근 가능
  •  캡슐화, 코드의 복잡성을 줄여줌 (캡슐화 : 변수들을 하나의 캡슐(class)로 감싸서 편리하도록)

 

보통 클래스 내부 클래스
 class A { }
 class B { }
 class A {
     class B {

     }
 }

 

 

 클래스 종류

  •  스태틱 클래스 : 외부 클래스의 멤버 변수 위치에 선언, static 키워드로 선언
  •  멤버 클래스 : 외부 클래스의 멤버 변수 위치에 선언, 인스턴스 멤버처럼 사용
  •  지역 클래스 : 외부 클래스의 메소드나 초기화 블럭 안에서 선언됨, 접근제한자 사용 불가
  •  익명 클래스 : 클래스 선언과 객체 생성을 도이에 하는 이름이 없는 클래스 (일회용)

 

class A {
	int num;
	class B { 	// 멤버 클래스 = 정적 멤버 클래스
		public B() {	// 생성자
			class BB{ 	// 지역 클래스
			}
		}
	}
}

 

 

class A {
	public A() {
		System.out.println("A클래스 생성됨");
	}
	class B { // 인스턴스 멤버 클래스
		int field1;
		public B() { // 생성자
			int field1;
//			static int field2;  -> 인스턴스 멤버 클래스에서는 static 사용 불가
			System.out.println("B객체 생성됨");
		}
		public void methodB () {}
//		static public void methodB2 () {}	-> static 사용 불가
	} // class B

	static class C { // static 정적 멤버 클래스
		int field1;
		static int field2; // static 사용 가능
		public C() { // 생성자 가능
			System.out.println("C객체 생성됨");}
			
		public void methodC() {}
		public static void methodC2() {}
		
	} // class C
	
	public void method() { // A의 메소드()
		// 로컬 영역
		int num = 10; 	// 지역 변수
		class D { // 지역 클래스
			int field1;
			public D() { // 생성자
				int field1;
//				static int field2; -> static 사용 불가
				System.out.println("D객체 생성됨");
			}
			public void methodD() {}
//			public static void methodD2() {} -> static 메소드 사용 불가
		} // class D
		D d = new D(); // 인스턴스 생성
		d.field1 = 3;
		d.methodD();
	
	} // method
		
} // class A

		
	
	
	
public class Inner01 {
	public static void main(String[] args) {
		
		A a = new A(); // A인스턴스 생성
		A.B b = a.new B();
		b.field1 = 1;
		b.methodB();
		
		A.C c = new A.C();
		c.field1 = 1;
		c.methodC();
		A.C.methodC2(); // static method
		
		a.method();
		
	}

}
package com.coffee.inner;

import javax.swing.ButtonModel;

class Button{
	OnclickListener listener;
	
	void setOnClickListener(OnclickListener listener) {
		this.listener = listener;
	}
	
	void touch() {
		listener.onclick();
	}
	
	static interface OnclickListener {
		void onclick(); // 인터페이스 : 바디없고 세미콜론으로 끝나야함
	}
}

public class Inner02 implements Button.OnclickListener {
	public static void main(String[] args) {
		
	}

	@Override
	public void onclick() {
		
	}

}
package com.coffee.inner;

public class Inner03 {
	public static void main(String[] args) {
		
		Button button = new Button();
		
		button.setOnClickListener(new Inner02());
		button.touch();
	}

}
반응형

댓글