메모장

스레드(Thread) 와 파일 입출력 본문

JAVA/개념정리

스레드(Thread) 와 파일 입출력

Itchild 2024. 4. 7. 20:36
728x90
반응형

스레드 ( Thread )

 

[ 스레드 Thread ]

메모리를 할당받은 프로세스 (실행중인 프로그램) 에서

실질적인 작업을 수행하는 주체이다 ! - 우리 모두 개개인의 하나의 스레드 라고 생각해도 된다.

ex ) 쇼핑몰을 이용하는 고객 한명한명이 스레드 라고 생각 한다.

만약 재고가 5개 남은 상품이 있었을때

t1 (사용자1) -> 장바구니에 3개를 담았고

t2 (사용자2) -> 5개를 즉시 구매했다.

이랬을시 t1은 장바구니에만 담아놨고 실제로 물건은 t2에게 간다

// 따라서 현재 데이터가 어떤 상태인지가 중요하다.

 

※ 동기화 : // ex ) 동기화 하는것 -> 계좌 나 티켓팅

ex ) 동기화 안하는 것 - > 장바구니 // 장바구니에 담는다고 딴사람을 막을순 없다

// 스레드는 독립적으로 일하는 일원이기 때문에

// 공유자원을 어떤 스레드가 점유하고 있을때 ,

// 다른 스레드의 접근을 막아줘야 한다.

 

그렇다면 위 내용 중 프로세스는 무엇인가 ? 실행중인 프로그램 만 !! 보인다.

프로그램 --실행상태--> 프로세스

일(동작)할수있게 메모리(자원)를 할당받은 상태

 

프로세스가 진행되는 방식에 대해서도 알아보자 !

▶ 프로세스가 실행되는 방식

 

  • 선점형 방식 : 우선순위 순서대로 자원(메모리)을 할당받아 진행되는 방식 -> 기아현상(자원을 할당받지 못한다.)이 발생될 가능성이 있음 // 예전에 쓰던 방식

ex ) A 3개 B 1개 C 2개 라고 가정하고 A가 우선순위가 제일 높다고 했을때

우선순위 부터 쭉쭉쭉 실행되는데 우선순위가 낮은 c는 계속 대기하다가 본인 우선순위보다 높으면 알파벳이 들어오면 또 앞으로 나간다. 그래서 오래 기다리다가 실행 못할수 있음.

 

  • 시간분할 방식 : 시간을 동일하게 배분하여 골고루 실행될 수 있도록 진행하는 방식 -> 기존의 선점형 방식에서 우선순위가 낮아 오-래 기다린 프로세스의 우선순위를 높여주는 방식

=> OS(운영체제)의 '스케줄러' (프로세스를 어떤 방식으로 실행시키는지 방식 이다 )

package class01;

// [스레드 Thread]
// 이미 JAVA에서 구현한 Thread 클래스를 가져다가 사용
// 코드를 재사용할 예정
// => 상속 
class Th01 extends Thread{

	@Override
	public void run() {
		for (int i = 1; i < 10; i++) {
			System.out.println("Thread 01 " + i);
		}
	}
	
}
class Th02 extends Thread{
	// 이슈가 안났으면 ? 기본생성자가 이미 숨어있구나 ? 
	@Override
	public void run() { // Thread에 핵심이 되는 메서드
		for (int i = 1; i < 10; i++) {
			System.out.println("Thread 02 " + i);
		}
	}
	
}
public class Test01 {

	public static void main(String[] args) {
		Th01 t1 = new Th01(); // 생성
		// 생성이 되면 , 즉시 대기상태가 됨 
		Th02 t2 = new Th02();
		
		// 쇼핑몰을 이용하는 고객 하나하나가 스레드 라고 생각 
		// 수행
		t1.start(); // 스레드 객체야, 일해 ! // 너 일해 켜놓고 
		t2.start();  // -> run()메서드를 실행시킴 // 너도 일해  
		
		// 스레드 객체들은 현재 독립적으로 일을 수행하고 있구나! --> 요것만 이해하면 됨 
		
		// start()로 인해 run()을 수행하게 되고, 주어진 run()을 수행하게 되면 
		// 데드 상태가 됨
		// 가지고 있던 메모리를 다 해제 해지 한다. 자기가 점유하고 있던 메모리를 
		// 다시 돌려준다.
		
		// 스레드 생명주기(라이프 사이클)
		// 생성 -> 대기 -> 수행 -> 데드
		// 블록 : 자원(메모리)을 할당받지 못하도록 막아둔 상태
		// 대표적인 스레드 블록상태  : sleep
		
		  for(int i=1;i<=10;i++) {
		         System.out.println(i);
		         try {
		            Thread.sleep(1000); // 1000 == 1초
		         } catch (InterruptedException e) {
		            // TODO Auto-generated catch block
		            e.printStackTrace();
		         }
		      }
	}

}
 

예시 ) 티켓을 구매하려는 세 사람

package class01;

//			ex )  동기화 하는것 -> 계좌 나 티켓팅 
// 동기화 :    ex ) 동기화 안하는 것 - > 장바구니 // 장바구니에 담는다고 딴사람 막을순 없다  
// 스레드는 독립적으로 일하는 일원이기 때문에 
// 공유자원을 어떤 스레드가 점유하고 있을때 ,
// 다른 스레드의 접근을 막아줘야 한다.



class Person extends Thread{
	//thread.start() - > run()메서드가 수행
	Ticketting t=new Ticketting(); // 객체 선언이 지금 중요한 부분이 아니라 일단 선언

	@Override
	public void run() {
		t.pay();
	}
}
class Ticketting { // Person 객체들이 사람들이 공유자원인 티켓을 구해하는 로직 
	static int ticket = 2; // 공유 자원 매표소 같은곳 
	// 공유자원, 클래스 변수 // 누구든지 사간다면 티켓이 있는지 없는지 봐야한다.
	synchronized void pay() { // 공유자원을 건드리는 얘가 문제다 
		if(ticket>0) {
			System.out.println(Thread.currentThread().getName()+"구매성공!");
			ticket--;                            // get으로 받았으므로 private 이다
		}
		else {
			System.out.println(Thread.currentThread().getName()+"구매실패ㅠㅠ...");
		}
		System.out.println("남은티켓: "+ticket);
	}
}


public class Test02 {

	public static void main(String[] args) {

		Person p = new Person(); // 스레드를 상속받은 
		Thread t1=new Thread(p,"홍길동");
		Thread t2=new Thread(p,"코난");
		Thread t3=new Thread(p,"짱구");

		t1.start();
		t2.start();
		t3.start();

		// 각각의 일을 할수 있는 스레드를 만들었다 
		//홍길동이 티켓을 보았을땐 2개 코난이 티켓을 봤을땐 두개 
		//짱구가 봤을땐 1개 여서 또 구매 
		// 사람의 이름을 멤버변수로 선언 한적이 없어서 스레드에 이름을 부여해줌 
	}
}
 

 

파일 입출력

 

[파일입출력]

파일 : 사진, 영상, 음성파일, 엑셀, 문서, 텍스트문서,... // 파일의 종류들

웹에서는 사진 파일

java에서는 .txt 로 실습할 예정

 

C:\HONG\resource // 저장할 곳

package class04;

import java.io.File; 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
// 지금까지는 콘솔이랑 자바랑 대화 시켰지만  
// 운영체제(컴퓨터)랑 자바랑 대화를 시킬 예정

public class Test01 {

	public static void main(String[] args) {

		// ▶ 1. 파일 생성하기 // 기본생성자가 없다 // 우리가 경로를 작성해줘야 한다.
		File file = new File("C:\\HONG\\resource\\test.txt"); // 파일 기본 생성자가 없어
		// 파일에게는 default 생성자가 없다
		// 해당파일이 존재하지 않으면, 하나 새로 생성해준다 ! <- 이런뜻
		try {
			file.createNewFile();
		} catch (IOException e) { // IO 랑 관련된것은 항상 try catch를 해줘야 한다.
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally { // 마무리로 확인해주기 
			System.out.println("파일 객체생성 완료 !");
		}

		// ▶ 2. 파일 읽어오기
		try {
			FileInputStream fis = new FileInputStream("C:\\HONG\\resource\\test.txt");
			// FileInputStream fis = new FileInputStream(file);

			// 내가 뭐라고 썼는지 몇번 읽어와야되는지 뭔지 몰라 while
			int data; // 얘가 반환을 int 로 하는 바람에
			while ((data = fis.read()) != -1) {
				// 읽어온 데이터가 -1 이면 "다 읽었다."
				// c언어는 마지막 끝나면 end of file이라 하는데
				// 자바는 int 라서 -1이면 다 읽었다고 표현한다
				System.out.println((char) data);
			}
			System.out.println();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally { // 마무리로 확인해주기
			System.out.println("fis객체로 파일 읽어오기 작업 완료!");
		}

		// ▶ 3. 파일 작성하기
		try {
			FileOutputStream fos = new FileOutputStream("C:\\HONG\\resource\\test.txt", true);
			// 생성자에 작성한 파일이 존재하지 않으면 새로 생성 해주고
			// 파일이 존재하면 !!! 덮어 쓰기 !!! 된다.
			// 파일이 존재할때 이어쓰기 하고 싶으면 ? (, true) 두번째 인자에 true를 쓰면 된다.

			// 얘네가 문자로 소통하는게 아니라 정수로 소통한다.
			fos.write(65); // 'A'
			fos.write(97); // 'a' -> 아스키 코드

			// ★★★★★★★
			// OS와 소통하던 통로를 직접 닫아주지 않으면 다음 수행시 문제가 발생할 수도 있다.
			fos.flush();
			fos.close();
			// 안닫았을시 문제가 생기는 애들 ! 꼭 닫아줘야함
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			System.out.println("fos객체로 파일 작성하기 작업 완료!");
		}
	}
}
 

[예제 문제 1]

D:\HONG\resource\test01.txt 파일이 있습니다.

정수가 1개 작성되어있습니다.

ex) 2 => 12

입력되어있는 정수는 짝(홀)수입니다.

        // 1. 파일 생성하기
		File file = new File("C:\\HONG\\resource\\test.txt");
		try {
			file.createNewFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			System.out.println("파일 객체생성 완료!");
		}

		// 2. 파일 읽어오기
		String a = "";

		try {
			FileInputStream fis = new FileInputStream("C:\\HONG\\resource\\test01.txt");

			int data;
			try {
				while ((data = fis.read()) != -1) {
					System.out.print((char) data);
					if (data % 2 == 1) {
						a = "홀";
					} else {
						a = "짝";
					}
				}

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} finally {
			System.out.println();
			System.out.println("입력하신 수는 " + a + "수 입니다.");
		}
 
// 강사님 코드와 비교  
// "유지보수 용이"
      final String path_START="D:\\KIM\\resource\\"; // 선언부에 선언해주기
      final String path_FILE01="test01";
      final String path_FILE02="test02";
      final String path_END=".txt";

      try { // 파일 읽어오기
         FileInputStream fis=new FileInputStream(path_START+path_FILE01+path_END);

         int data; // 변수 설정
         String num=""; // 문자열 변수
         while( (data=fis.read()) != -1 ) { // -1이 되면 다 읽은 뜻으로 -1이 되지않을때 까지 반복
            num+=(char)data; // data를 형변환 해서 num에 " " 로 연결해서 담는다.
         }
         System.out.println(num);
         data=Integer.parseInt(num); // 정수로 바꾸기
         System.out.println(data);
         if(data%2==0) { // data가 짝수 일때 
            System.out.println("짝수");
         }
         else { // 아닐때
            System.out.println("홀수");
         }
      } catch (FileNotFoundException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      } finally {
         System.out.println("fis객체로 파일 읽어오기 작업 완료!");
      }
 

[문제 2]

D:\HONG\resource\test02.txt 파일이 있습니다.

아무내용도 작성되어있지않습니다.

abcde...xyz까지 작성해주세요!~~

// 1. 파일 생성하기
		File file2 = new File("C:\\HONG\\resource\\test02.txt");
		try {
			file2.createNewFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			System.out.println("파일 객체 생성 완료 !");
		}

		// 3. 파일 작성하기
		try {
			FileOutputStream fos = new FileOutputStream("C:\\HONG\\resource\\test02.txt");
        // FileOutputStream fos=new FileOutputStream(path_START+path_FILE02+path_END);
        // 강사님 풀이 // 이 부분 말고는 비슷하다.
			
            int result = 0;
			for (int i = 97; i <= 122; i++) { // 아스키 코드
				result = i;
				fos.write((char) result);
			}

			fos.flush();
			fos.close(); // 꼭 닫아주기 

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			System.out.println("fos객체로 파일 작성하기 작업 완료 !");
		}
 
package class04;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test04 {

	public static void main(String[] args) {

		// ▶ 4. 사진 복사하기 
		
		final String path="C:\\\\HONG\\\\resource\\\\";
		final String fileName="짱구.jpg";
		final String fileCopy="짱구 - 복사본.jpg";
		
		try {
			
			FileInputStream fis=new FileInputStream(path+fileName); // 파일 읽어오기
			FileOutputStream fos=new FileOutputStream(path+fileCopy); // 파일 작성하기
			
			int data;
			byte[] buff=new byte[10000]; // 10000 byte 씩 받는다
			while((data=fis.read(buff))!=-1) { //-1로 종료되기 전까지
				// 0 부터 data 까지 만큼 버퍼배열로 풀어
				/////System.out.println("확인");
				fos.write(buff, 0, data); //버퍼배열, 0 시작부터 , 끝 data 까지
			}
			
			fos.flush();
			fos.close(); // 꼭 닫아주기			
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			System.out.println("사진 실습 완료!");
		}
	}
}
 

 

 

728x90
반응형

'JAVA > 개념정리' 카테고리의 다른 글

MVC 패턴 중 Model 공부  (0) 2024.04.07
MVC 패턴  (0) 2024.04.07
예외 와 예외처리  (0) 2024.04.07
컬렉션 프레임 워크  (0) 2024.04.06
객체배열  (1) 2024.04.06