- 프로세스

실행된 프로그램

운영체제로부터 시스템 자원을 할당받는 작업의 단위를 의미한다.

자바 프로그램은 운영체제 대신 JVM에 의해 자원을 할당받는다.

 

- 쓰레드 (Thread, 단일 쓰레드)

프로세스의 특정한 수행 경로

프로그램의 처리 경로

프로그램의 흐름

직렬적이다.

 

- 멀티쓰레드

하나의 프로세스를 동시에 처리하는 것처럼 보이지만 사실은 매우 짧은 단위로 분할해서 차례대로 처리한다.

짧은 단위로 분할해서 차례대로 처리한다.

병렬적이다.

 

여러 개의 처리 경로를 가질 수 있게 한다.

한 개의 처리 경로를 여러 개로 나누어 동시 작업이 가능해진다.

JSP (Java Server Page)가 대표적인 멀티 스레드 응용 프로그램이다.

 

- 쓰레드의 장단점

장점 단점
효율성 증가
처리량 증가
처리비용 감소
복잡하고 설계가 어려움
자원의 공유 문제
하나의 쓰레드 문제 발생 시 전부 다 문제 발생
(교착상태 - DeadLock)

 

 

- 교착 상태

멀티 쓰레드 중 쓰레드 간의 대기 상태가 종료되지 않아서 무한정으로 대기만 하는 비정상적인 상태를 의미한다.

 

대비 방법 : 조건문을 통해 교착상태를 판단하고 다시 깨워준다.

 

 

- 동기화 (synchronized)

하나의 필드를 여러 쓰레드가 동시에 사용하지 못하도록 막는 것을 말한다.

 

synchronized(this) {
		다른 쓰레드가 접근 못하게 할 피드
    }

 

 


Thread 사용하기!

 

1. 메인메소드가 존재하는 ThreadTest 클래스

public class ThreadTest {
	public static void main(String[] args) {
		
		// 멀티 쓰레드를 만드는 방법
		
		// 1. Thread 클래스를 상속한 뒤, run 메소드 재정의
		// 상속받은 클래스를 객체로 만들고 .start()
		MyThread t1 = new MyThread();
		t1.start();
		
		// 2. Runnable 인터페이스를 지정 받은 후 run메소드를 재정의
		// Thread 타입의 객체를 만들며 그 Runnable 객체를 넘겨준다.
		// 이후에 Thread객체.start()
		
		MyRunnable r = new MyRunnable();
		Thread t2 = new Thread(r);
		
		t2.start();
		
	}
	
}

 

2. Thread 클래스를 상속받은 MyThread 클래스

public class MyThread extends Thread {

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println("☆");
			try {
				// Thread를 상속받았기 때문에 sleep으로 작성해도 사용할 수 있다.
				sleep(1000);
			} catch (InterruptedException e) {
			}
		}
	}
}

 

3. Runnable 인터페이스를 지정받은 MyRunnable 클래스

public class MyRunnable implements Runnable{

	@Override
	public void run() {
		for (int i = 0 ; i < 10; i++) {
			System.out.println("♥");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}
		}
	}
}

 

위 코드의 결과

sleep(1000)을 주었기 때문에 1초씩 멈췄다가 나오는 것을 확인 할 수 있다.

sleep(1000)을 주지 않으면 한꺼번에 하얀별이 나오고 까만 하트가 나온다.

이는 동시에 실행되지만 속도가 너무 빨라서 한꺼번에 나오는 것이다.


- 파일 입출력

 

- Writer (입력)

FileWriter > BufferedWriter > 파일에 입력

 

 

- File Writer  

경로에 있는 파일을 쓰기 위해서 가져오기

※ 파일이 없으면 그 이름 그대로 파일을 생성해준다.

하지만 경로가 이상한 경우에는 (폴더가 잘못된 폴더인 경우) 폴더를 생성해주지 않고, 예외가 발생한다.

 

new FileWriter ("파일경로/파일명.확장자");	// 덮어쓰기 모드
new FileWriter ("파일경로/파일명.확장자", true); 	// 추가모드

 

 

- BufferedWriter 

버퍼를 이용해서 파일 작성을 작성한다.

bw.write("문자열")		// 버퍼에 문자열 쓰기
bw.close()			// 파일에 적용/ 버퍼에 있는 데이터들을 파일에 써주면서 버퍼 닫기

 

 

-Reader (출력)

FileReader > BufferedReader > 파일에 등록

 

 

- FileReader

경로에 있는 파일을 읽기 위해 가져오기

※ 파일이 없으면 예외 발생 (FNFE)

 

new FileReader ("파일경로/파일명.확장자");		// 읽기모드

 

 

-BufferedReader 

버퍼를 이용해서 파일 읽기

br.readLine() 	// 버퍼를 이용해서 한줄 씩 읽기

 


파일 입출력 사용해보기!

 

1. 파일 쓰기

public class WrtierTest {
	public static void main(String[] args) throws IOException{
		System.out.println("파일을 쓰기 위한 준비 시작");
		FileWriter fw = new FileWriter("data.txt", true);
		System.out.println("파일 준비 완료");
		
		BufferedWriter bw = new BufferedWriter(fw);
		System.out.println("버퍼 준비 완료");
		
		// 버퍼에다가 작성해놓은 것은 플러쉬 과정을 거쳐야한다.
		// 여기서 플러쉬과정을 거치지 않으면 작성한 내용이 버퍼에만 남고 작성되지 않는다.
		bw.write("버퍼쓰기\n");
		bw.write("data메모장에 글쓰기\n");
		bw.write("자바\n");
		bw.write("JAVA\n");
		
		// 버퍼는 닫으면서 플러쉬를 하기 때문에 플러쉬를 하고 닫는 것보다 바로 닫는 것이 좋다.
		bw.close();
		System.out.println("파일 작성 완료");
		
	}
}

위 코드의 결과_콘솔창
파일에 작성된 화면

File Writer을 사용하면 파일을 따로 만들지 않아도 작성한 경로에 작성한 이름 되어 파일이 생성되고

거기에 내용이 적히는 것을 확인할 수 있다.

 

 

2. 파일 읽기 

public class ReaderTest {
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new FileReader("data.txt"));
		
		while(true) {
			String line = br.readLine();
			if(line == null) {
				break;
			}
			System.out.println(line);
		}
	}
}

위 코드의 결과

복사했습니다!