160328: 11회차
종료하기 전 티스토리 네이버 로그아웃 할 것
1. 툴
동일
추가시:
2. 폴더
동일
추가시:
3. 사용할 사이트
동일
추가시:
4. 공부하는 것
오늘은 IO 랑 Thread!
IO Stream - 스트림은 연속적인 데이터의 흐름!
<<현재 실행하고 있는 프로그램을 기준으로>>
가지고 있는 데이터를 내보내는 것: 출력 스트림
외부 장치에서 프로그램으로 데이터를 가져오는것: 입력 스트림
스트림은 단반향 구조여서 한 곳으로만 데이터가 전송됨 (출발 -> 목적 지정)
그래서 입력 스트림 따로 / 출력 스트림 따로 만듬 (입구와 출구가 다름) - 단방향 구조!
아오씨 발목 건조해
한글은 유니코드 어쩌구 때문에 InputStream / OutputStream(1바이트짜리) 못 쓰고 Reader랑 Writer(2바이트짜리) 써야함.
바이트 단위 처리 2바이트 문자단위
(한글 처리 불가능) (한글 처리 가능)
-------------------------------------------------------------------------------
InputStream 기본 입력 스트림 클래스 Reader
OutputStream 기본 출력 스트림 클래스 Writer
FileInputStream 파일 입력 스트림 클래스 FileReader
FileOutputStream 파일 출력 스트림 클래스 FileWriter
BufferedInputStream 버퍼 입력 기능 클래스 BufferedReader
BufferedOutputStream 버퍼 출력 기능 클래스 BufferedWriter
DataInputStream 데이터 타입을 지정하여 입력할수 있는 클래스
DataOutputStream 데이터 타입을 지정해서 출력할수 있는 클래스
ObjectInputStream ois; Class 객체를 읽어 올 수 있습니다.
ObjectOutputStream oos; Class 객체를 출력 할 수 있습니다.
그렇다
인풋스트림 / 아웃풋스트림에 앞에 파일 붙이면 - 파일로 바이너리 데이터를 입력받고 / 내보내고
이번에 앞에 버퍼드 붙이면 중간에 버퍼를 사용해서 쌓아놨다가 한꺼번에 데이터를 읽어오고 / 내보내고
근데 데이터는 2바이트짜리가 없음 ㅇㅇ - 이거는 Data 타입을 (인트 불리언 이런거) 유지하면서 읽어오고 / 내보내고
Object 붙이면 메모리에 있는 (실제 객체의) 데이터를 가져오고 / 내보내고
File 클래스는 파일의 경로명을 다루는 클래스!
파일 객체는 파일과 디렉터리를 다 다룸!
- 삭제랑 디렉터리 생성 등과 같은 걸 할 수 있음
근데 이거 내용을 읽고 쓰려고 스트림을 이용함 - File 객체랑 스트림을 연결해서 파일에 접근함
예제는 디렉터리 만드는 것
package day11;
import java.io.File;
import java.util.Date;
class FileDirectoryMaking {
public boolean make(String fname) {
// 존재하지 않는 파일 만들기
File f = new File(fname); // file 객체 생성 :>
if (f.isDirectory() && f.exists()) { // f가 디렉토리면서 / 존재하면
System.out.println(fname + "가 이미 존재함");
return false; // 끝내야징
}
// 위에서 짤리면
f.setLastModified(new Date().getTime());// 수정일
// 파일객체.setLastModified(현재 날짜) - 현재 날짜 지정 가능
return f.mkdir();
// 디렉토리 만들기 :> - 근데 위치 지정을 안해서 javatest 안에 만들어짐..
// D:\javadb\workspace\javatest 요기 가보면 있음 :>
// eclipse에서는 f5 해주면 확인 가능
}
public boolean renameTo(String fname, String newName) {
File f = new File(fname); // 존재하는 파일 이름 바꾸기
if (!f.exists()) {
System.out.println(fname + "가 없다.");
return false;
}
f.setLastModified(new Date().getTime()); // 수정일
return f.renameTo(new File(newName));
// File 객체의 rename 메소드를 통해서 f가 가리키는 디렉토리의 이름을 바꿈
// 근데 이게 true 인 이유는 - 바꾸는게 성공하면 true를 리턴하니까래 ... -ㅅ-);;
}
public boolean delete(String fname) {
File f = new File(fname);
if (!f.exists()) {// 있어야 지우니까 존재만 찾으면 됨
System.out.println(fname + "가 없다.");
return false;
}
// cf f.deleteOnExit();
return f.delete(); // 지우는게 성공하면 true 리턴
}
}
public class FileDirectoryMakingMain {
public static void main(String[] args) {
FileDirectoryMaking fm = new FileDirectoryMaking();
System.out.println("aaa 디렉토리 생성: " + fm.make("aaa"));
System.out.println("bbb 디렉토리 생성: " + fm.make("bbb"));
System.out.println("디렉토리명 변경 : " + fm.renameTo("aaa", "ccc"));
System.out.println("디렉토리 삭제 : " + fm.delete("bbb"));
}
}
package day11;
import java.io.IOException;
public class ReadFromSystem1 {
public static void main(String[] args) {
byte[] b = new byte[1024];
//바이트 쓰는 이유는
//int java.io.InputStream.read(byte[] b) throws IOException
//이렇게 리드가 바이트를 받음. ... -_-) 귀찮당
int len = 0;
try {
System.out.println("데이터를 입력하세요: ");
len = System.in.read(b);
//len은 byte형 배열의 입력된 개수를 저장해줌 -_-);;같은 시스템인가보다
System.out.println(len);
} catch (Exception e) {
System.out.println("입력실패");
}
String str = new String(b, 0, len - 2);
//String(b의 , 0부터 , len-2까지) 출력
// String 생성자 중 파라미터가 3개 있는 것을 썼다는 얘기임
// 2 빼는 이유는 엔터가 2바이튼가봐 ... 이거 -2 지우면 엔터도 입력됨
System.out.println(str);
try {
System.out.println("데이터를 입력하세요: ");
len = System.in.read(b);
System.out.write(b, 0, len);
// 이것은 무엇인가... -_-);; ㅎㅎ
//아 쓰라고.. write군
System.in.close();
} catch (IOException e) {
System.out.println("입력실패");
}
}
}
BufferedReader - 한 줄씩 읽어옴
BufferedReader 메소드
설 명
String readLine()
한줄을 읽는다. "\n", "\r"을 만날때 까지 읽어온다.
- readLine() 메소드를 사용하면서 문자 읽기를 더 효율적으로 할 수 있게 됐다.
- 기존의 read() 메소드로 한 문자씩 읽어오는 것보다 한줄씩 읽어서 처리하기에 더 간편하다.
readLine은 \n이나 \r을 만날때 까지 읽어온다.
package day11;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
public class ReadFromFile {
public static void main(String[] args) {
String fname = "src\\day11\\ReadFromFile.java";
// String fname = "src/day11/ReadFromFile.java";
// String 객체명 = "(이클립스프로젝트의)폴더명\\패키지명\\파일명;
// 역슬래시: 2개 / 슬래시: 1개
// 이거는 버퍼 기능을 넣어서 파일 객체를 감싸줌
File f = new File(fname);
// 파일의 경로를 파일 객체에 넣음
String path = f.getAbsolutePath();
// 파일의 절대경로 반환
System.out.println(path);
try {
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
// 한 글자씩 읽어오면 힘드니까 buffer 기능 추가
StringBuffer sb = new StringBuffer();
// 어 변경될거니까 stringbuffer 씀!
String s = "";
while ((s = br.readLine()) != null) {
sb.append(s + "\n");
// \n 한 이유는 한라인씩 바꿔주려고 :>
}
s = sb.toString();
// 생략해도 되지만 그냥 해줬음
System.out.println(s);
br.close();
fr.close();
// 쓴거 다 close
} catch (Exception e) {
System.out.println(e.toString());
// 한번에 Exception으로 받으려고 File어쩌구Exception 안쓰고
// 그냥 Exception을 씀
}
}
}
- 버퍼를 쓰는 이유: 그냥 쉬우라고 -_-)
- 스트링버퍼에다가 하나씩 박아도 되긴 됨...
append 메소드 모르겠다
응이건 저장된 거 뒤에다가 더 추가하는 거랭
그리고 어렵다 ㅠㅠ
출처: http://zzing8300.tistory.com/104
------------------------------------------------------------------------------------
LineNumberReader는 파워복붙
package day11;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
public class ReadFromLine {
public static void main(String[] args) {
try {
System.out.println("데이타를 입력하세요");
InputStreamReader isr = new InputStreamReader(System.in);
//키보드에서 읽어오는것 :>
//밑에 라인넘버리더가 reader 타입을 파라미터로 받아서
//System.in을 변환작업 해주는거심
LineNumberReader br = new LineNumberReader(isr);
//읽어오는 법: 라인넘버리더 :>
StringBuffer sb = new StringBuffer();
String s = "";
while (!(s = br.readLine()).equals("999")) {//
sb.append(br.getLineNumber() + " " + s + "\n");
//999입력하기 전까지 입력받음
//getLineNumber는 줄 넘버값 써줌
}
System.out.println(sb.toString());
br.close();
isr.close();
} catch (Exception ee) {
System.out.println(ee.toString());
}
}
}
------어 이거 타입 질문 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ-------------
------------------------------------------------------------------------------------
package day11;
import java.io.*;
public class FileDirDemo1 {
public static void main(String[] args) {
/*
* System.in: 키보드 standard InputStream new InputStreamReader(System.in):
* 입력을 받아 문자 인코딩을 실행 new BufferedReader();: 입력받은 문자를 버퍼에 저장하는 역활과 저장소
* 역활을 함
*
* System.in ↑ InputStreamReader(System.in) ↑ new BufferedReader(new
* InputStreamReader(System.in))
*
* Call By Reference 사용
*/
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
// 오 버퍼드리더에 바로 넣음 (인풋스트림리더(시스템쩜인))
System.out.print("디렉토리를 입력해 주세요: ");
String directory = "";
try {
directory = in.readLine();// 키보드로부터 입력
} catch (Exception e) {
System.out.println("Error: " + e.toString());
}
File f1 = new File(directory);
if (f1.isDirectory()) {
System.out.println("검색 디렉토리 " + directory);
System.out.println("===============================");
String s[] = f1.list();
for (int i = 0; i < s.length; i++) {
//디렉토리와 파일 조합
File f = new File(directory + "/" + s[i]);
if(f.isDirectory()){
System.out.println(s[i] + ": 디렉토리");
}
else{
System.out.println(s[i] + ": 파일");
}
}
}//end if
else{
System.out.println("지정한 " +directory + " 는 디렉토리가 아님");
}
}
}
------------------------------------------------------------------------------------
FileWriter! - 파일 쓰기 객체! :>
package day11;
import java.io.*;
public class FileWriterDemo {
public static void main(String[] args) {
String source = "JAVA\n" + "JSP\n" + "EJB\n" + "OJT\n" + "가나다\n";
String fname = "";
try {
System.out.print("저장할 파일명을 입력하세요: ");
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
fname = in.readLine();
} catch (Exception e) {
System.out.println("Error: " + e.toString());
}
try {
FileWriter fw = new FileWriter(fname);
fw.write(source);
fw.close();
System.out.println("파일을 저장했습니다.");
FileReader fr = new FileReader(fname);
int i;
System.out.println("파일을 읽어 옵니다.");
// 한 문자를 읽어 들임, 파일의 끝이라면 -1을 읽음
while ((i = fr.read()) != -1) {
// read()는 리턴형이 int니까 캐릭터로 형변환해줘야함
// -1은 더 읽을 게 없는 것...
// The character read, or -1
// if the end of the stream has been reached
System.out.print(" (" + i + ") ");
System.out.print((char) i);
}
fr.close();
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
---------------------------------------------------------파일 오타
package day11;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
public class CopyFile {
public static void main(String[] args) {
try {
// File 객체를 프로그램 실행시의 인자를 이용하여 생성한다.
// 예를 들어, java CopyFile test.txt output.txt
// test.txt -> args[0]
// output.txt -> args[1]
// 파라미터를 2개를 받았는지 검사
if (args.length != 2) {
System.out.println("---------------- 에러 발생 ----------------");
System.out.println("usage: java CopyFile <원본파일명> <대상파일명>");
// 비 정상적인 종료: 0보다 큰값을 지정
System.exit(1); // 프로그램 종료
}
// 파일 객체 생성
File inputFile = new File(args[0]);// 소스파일명
File outputFile = new File(args[1]);// 생성될 파일명
// FileReader는 데이터를 읽어오는 역할을 합니다.
FileReader in = new FileReader(inputFile);
// FileWriter는 쓰는 역할을 합니다.
FileWriter out = new FileWriter(outputFile);
int c;
// FileReader 클래스 객체에서 파일의 끝까지 읽어서
// FileWriter 클래스에 기록을 합니다.
// 한문자를 읽어 들임, 문자는 내부적으로 문자코드에 기반한
// 숫자형태로 변경되어 처리됩니다.
// EOF -1
while ((c = in.read()) != -1) {
// 파일에 출력
out.write(c);
}
System.out.println("파일 복사가 완료되었습니다.");
// 스트림을 닫아줍니다.
in.close();
out.close();
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
------------------------------------------------------------------복붙이니까 해보기
package day11;
import java.io.*;
public class ReadAndWriteFromFile {
public void readFile(String fn) throws IOException {
FileReader fr = new FileReader(fn);
BufferedReader br = new BufferedReader(fr);
StringBuffer sb = new StringBuffer();
String temp = "";
while ((temp = br.readLine()) != null) {
sb.append(temp + "\n");
}
System.out.println(sb.toString());
br.close();
fr.close();
}
public void readnwrite(String fn, boolean append) throws IOException {
String s = null;
FileWriter fw = new FileWriter(fn, append);// append true
//FileWriter(ㅁㅁ, true) - 기존의 값에 이어가기
//FileWriter(ㅁㅁ, false) - 기존의 갚을 덮어쓰기
PrintWriter pw = new PrintWriter(fw);// flush false
// PrintWriter pw=new PrintWriter(fw, true);//flush true
while (!(s = readbuff()/*문자열리턴*/).equals("999")) { // CTRL+C
pw.println(s);
pw.flush();// PrintWriter(fw, true)일 때는 필요없다.
}
pw.close();
fw.close();
}
public String readbuff() throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
return br.readLine();
}
public static void main(String[] args) {
String fname = "aaa.txt";
ReadAndWriteFromFile baw = new ReadAndWriteFromFile();
try {
baw.readnwrite(fname, false);// clear
//baw.readnwrite("aaa.txt",true);//append
baw.readFile(fname);
} catch (Exception ex) {
System.out.println(ex);
}
}
}
데이터 주고받기!!
DataInputStream과 DataOutputStream 이용
package day11;
import java.io.*;
public class WritingDatas {
public void writingData(String fname, boolean append) throws IOException {
FileOutputStream fos = null;
DataOutputStream dos = null;
try {
fos = new FileOutputStream(new File(fname), append);
dos = new DataOutputStream(fos);
dos.writeBoolean(append);
dos.writeByte(123);
dos.writeChar(75);
dos.writeDouble(34.56);
dos.writeFloat(345.23f); // float는 F
dos.writeInt(123);
dos.writeLong(345L); // long 타입은 L
dos.writeUTF("홍길동"); // 문자열은 메소드 이름이 UTF
dos.flush(); // fos.close();
} catch (FileNotFoundException e) {
System.out.println("잘못된 파일이름을 입력했습니다.");
}
}
public void readingData(String fname) throws IOException {
try {
FileInputStream fis = new FileInputStream(new File(fname));
DataInputStream dis = new DataInputStream(fis);
System.out.println("append가능? :" + dis.readBoolean());
System.out.println("read byte :" + dis.readByte());
System.out.println("read char :" + dis.readChar());
System.out.println("read double :" + dis.readDouble());
System.out.println("read float :" + dis.readFloat());
System.out.println("read int :" + dis.readInt());
System.out.println("read long :" + dis.readLong());
System.out.println("read utf :" + dis.readUTF());
dis.close();
} catch (FileNotFoundException e) {
System.out.println("잘못된 파일이름을 입력했습니다.");
}
}
public static void main(String[] args) {
WritingDatas wd = new WritingDatas();
try {
wd.writingData("writed.txt", false);
wd.readingData("writed.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
}
// BYTE 형태로 저장이 되어서 txt 파일을 읽을 수는 없음...
// 육안으로는 불가능 - 컴퓨터는 가능
// 왜 이따구 - inputstream 이라서 -_-);;
// 데이터 타입 유지할 수가 없음...
// 바이너리는_구진것_같다.
// 근데 리더라이터는_무거운것_같다.
------------------------------------------------------------------------------------
>>>> ObjectInputStream & ObjectOutputStream
오브젝트도 읽고 / 내보내고 가능... -_-);; - ㅇ...
인스턴스 파일 저장하는 과정 이름: 직렬화
직렬화: 얼린다 (-_-);; - 유지는 하는데 사용은 못하게 세이브는 하는것... - 메모리에서 살짝 다른 데 올려놓는 것
-serialization
도로 내보내는 과정: 역직렬화
역직렬화: 직렬화를 통해 유지한 오브젝트를 메모리에 다시 올려놓는 것.
직렬화의 대상이 되는 인스턴스의 클래스는 java.io.Serializable 인터페이스를 구현해야 한다. - implements 하라고...
package day11;
import java.io.*;
//import java.io.FileInputStream;
//import java.io.FileOutputStream;
//import java.io.IOException;
//import java.io.ObjectInputStream;
//import java.io.ObjectOutputStream;
//import java.io.Serializable;
public class Circle implements Serializable {
int xPos;
int yPos;
double rad;
Circle() {
}
Circle(int x, int y, double r) {
xPos = x;
yPos = y;
rad = r;
}
void showCircleInfo() {
System.out.printf("[%d, %d] \n", xPos, yPos);
System.out.println("rad :" + rad);
}
public static void main(String[] args) throws IOException, ClassNotFoundException{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("Object.ser"));
out.writeObject(new Circle(1, 1, 2.4));
out.writeObject(new Circle(2, 2, 4.8));
out.writeObject(new String("String implements Serializable"));
out.close();
//요기까지가 인스턴스 저장
ObjectInputStream in = new ObjectInputStream(new FileInputStream("Object.ser"));
Circle cl1 = (Circle)in.readObject();
Circle cl2 = (Circle)in.readObject();
String message = (String)in.readObject();
in.close();
//인스턴스 복원
cl1.showCircleInfo();
cl2.showCircleInfo();
System.out.println(message);
//복원된 정보 출력
}
}
직렬화 역직렬화
1. 확장자는 상관 없음
2. 이거왜함?
>>>>> transient - 직렬화의 대상에서 제외됨.
얘는 직렬화의 친구인데 직렬화 안하고 (숨기고) 싶을 때 쓰는 애임
내 파일 누가 가져가서 실행할 때 이 내용은 안나옴 ㅇㅇ
직렬화 하는 이유는
객체 내용을 입출력형식에 구애받지 않고 객체를 파일에 저장함으로서 응 그것들을 네트워크를 통해서 손쉽게 교환이 가능하다...
가 무슨 말이냐면 그냥
객체 내용을 바이트로 변환해서 파일이나 네트워크를 통해서 스트림(송수신)이 가능하게 하는 것 :>
이거 왜 쓰냐면
RMI(뭔지모름-원격객체통신 어쩌구래) - 는 이거는 객체를 그대로 이동시켜야하는데 이럴떄 바이트 어쩌구라서 직렬화 필요
리모트 - 메쏘드 - 인보케이션 (-_-);;
http://lueseypid.tistory.com/42
http://devbox.tistory.com/entry/Java-%EC%A7%81%EB%A0%AC%ED%99%94
직렬화 넘나 어려운것...
직렬화(Serialization)
- 객체를 데이터스트림(스트림에 쓰기(write)위한 연속적인(serial) 데이터)으로 만드는 것.
- 예) 객체를 컴퓨터에 저장했다가 꺼내 쓰기. 네트워크를 통한 컴퓨터 간의 객체 전송.
역직렬화(Deserialization)
- 스트림으로부터 데이터를 읽어서 객체를 만드는 것.
package day11;
import java.io.*;
public class PersonalInfo implements Serializable{
String name;
transient String secretInfo;
int age;
transient int secretNum;
public PersonalInfo(){}
public PersonalInfo(String name, String sInfo, int age, int sNum){
this.name = name;
secretInfo = sInfo;
this.age = age;
secretNum = sNum;
}
public void showCircleInfo(){
System.out.println("name : " + name);
System.out.println("secret info: " + secretInfo);
System.out.println("age : " + age);
System.out.println("secret num : " + secretNum);
System.out.println("");
}
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
PersonalInfo p1 = new PersonalInfo("Dave", "human", 3, 42);
PersonalInfo p2 = new PersonalInfo("David", "person", 66, 1);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("obj.ser"));
//인스턴스 저장
out.writeObject(p1);
out.writeObject(p2);
// p1.showCircleInfo();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("obj.ser"));
//인스턴스 복원
PersonalInfo p3 = (PersonalInfo)in.readObject();
p3.showCircleInfo();
PersonalInfo p4 = (PersonalInfo)in.readObject();
p4.showCircleInfo();
PersonalInfo p5 = (PersonalInfo)in.readObject();
p5.showCircleInfo();
//p5까지 만들면
/*
* Exception in thread "main" java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2608)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1319)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at day11.PersonalInfo.main(PersonalInfo.java:47)
* */
// 이게 뭔뜻이여 ㅡㅡ
// end of file exception 이었습니다 ^^
//p1.showCircleInfo();
}
}
. 스레드 스케줄러에 의해서 스레드의 여러상태중 실행상태로 변경할 수 있다.
. 스레드의 상태는 준비상태, 실행상태, 대기상태, 정지상태가 있다.
. 스레드는 자원을 공유하는 특징이 있어 멤버필드와 static 필드를 공유한다.

스레드의 run()메소드를 호출한다.
- stop(): 스레드 실행을 완전히 종료 한다.
- getName(): 쓰레드의 이름을 알려줍다.
- Thread.currentThread()는 현재 실행중인 쓰레드를 알려준다.
이 프로세스는 단일 쓰레드 환경이 된다.
Runnable인터페이스를 구현해야 한다.
1. 스레드를 이용하지 않은 경우
>>>>> NonThread.java
2. Thread 클래스를 상속받은 경우
- CallBack Method: JVM이 자신의 실행 스케쥴러를 만들고 거기에 등록된 순서에 따라 자동
호출하는 메소드
파워복붙
package day11;
class MyThread extends Thread { //쓰레드를 부모로 가짐
//그래서 이거 객체로 만들면 멀티쓰레드임
//쓰레드의 자식이니까 얘도 쓰레드
//엄마건 내거 상속인것
private int num;
private String name;
public MyThread(String a, int b) {
name = a;
num = b;
}
public void run() { // Callback 메소드
for (int i = 0; i < num; i++) {
System.out.println(name + " : " + i);
}
}
}
public class ThreadTest1 {
public static void main(String args[]) {
MyThread t1 = new MyThread("first", 1000);
MyThread t2 = new MyThread("second", 1000);
MyThread t3 = new MyThread("third", 1000);
t1.start();
t2.start();
t3.start();
//이거 돌리면 순위가 매번 다름 ㅇㅇ 쓰레드 스케줄러 마음!!
}
}
3. Runnable 인터페이스를 사용한 경우
- 스레드 내용을 가지고 있는 클래스가 추가적인 기능이 필요해 다른 클래스를 상속받는 경우는
Runnable인터페이스를 implements(구현)해서 사용한다.
package day11;
class ThreadOne implements Runnable {
// 자바는 다중 상속이 안됨으로 클래스가
// 특정 클래스를 상속할 필요가 있는 경우는 반드시
// Runnable 인터페이스를 구현해야 한다.
private int num;
private String name;
public ThreadOne(String a, int b) {
name = a;
num = b;
}
public void run() {
for (int i = 0; i < num; i++) {
System.out.println(name + " : " + i);
}
}
}
public class ThreadTest2 {
public static void main(String args[]) {
// Runnable Interface를 구현한 클래스 객체를
// Thread 클래스의 생성자로 할당합니다.
Thread t1 = new Thread(new ThreadOne("first", 1000));
Thread t2 = new Thread(new ThreadOne("second", 1000));
Thread t3 = new Thread(new ThreadOne("third", 1000));
t1.start();
t2.start();
t3.start();
}
}
runnable - interface라서 implements 해주기 때문에
thread - 얘가 class니까 만약에 다른 애를 extends 했을 경우에 Runnable을 써주면
쓰레드 대신 쓸 수 있음 - 그래서 씀
4. 쓰레드 기본메소드와 특징확인
package day11;
class MyRuns implements Runnable {
public void run() {
show();
}
public void show() {
for (int i = 0; i < 100; i++) {
if (((Thread.currentThread()).getName()).equals("a")) {
//스레드가 여러개일 때 현재 스레드.의이름.이 a냐고?(맞으면: true / 아님 false)
System.out.print("a");
// System.out.print("[A"+i+"]");
} else if (((Thread.currentThread()).getName()).equals("b")) {
// System.out.print("[B"+i+"]");
System.out.print("b");
} else if (((Thread.currentThread()).getName()).equals("c")) {
// System.out.print("[C"+i+"]");
System.out.print("c");
} else {
System.out.print("[" + Thread.currentThread().getName() + i + "]");
}
}
}
}
public class MyRunsMain {
public static void main(String[] args) {
MyRuns mr1 = new MyRuns();
Thread t1 = new Thread(mr1, "a");
Thread t2 = new Thread(mr1, "b");
Thread t3 = new Thread(mr1, "c");
// Thread t3=new Thread(mr1);
t1.start();
t2.start();
t3.start();
}
}
//이 코드 돌리면 점유율을 알 수 있슴니다 -_-)ㅋ
5. Thread와 자원 공유 - 멤버필드, static필드
- 같은자원(같은 객체의 멤버필드)을 여러개의 쓰레드가 공유할 수 있다.
- 문제점발생: 좌석예약, 계좌입출금 등등
- 문제점은 동기화 처리(synchronized)로 해결할 수 있다.
오예 씽크로나이즈드!!
동기화! :D 이예~~~~~~~~~~~~~~ 책에서본거~~~~~~~~~~ 내용은 모르지만~~~
지네 처리할 것을 보장하는 식으로 해결함 ㅇㅇ 넘나조은것
package day11;
class MemberPrint implements Runnable {
//임플리먼츠 때문에 쓰레드임 :>
private int i = 0; //
public void run() {
show();
}
public void show() {
for (; i < 100; i++) {
if (((Thread.currentThread()).getName()).equals("a")) {
System.out.print("[A" + i + "]");
} else if (((Thread.currentThread()).getName()).equals("b")) {
System.out.print("[B" + i + "]");
} else if (((Thread.currentThread()).getName()).equals("c")) {
System.out.print("[C" + i + "]");
}
}
}
}
public class MemberPrintMain {
public static void main(String[] args) {
MemberPrint mr1 = new MemberPrint();
Thread t1 = new Thread(mr1, "a");
Thread t2 = new Thread(mr1, "b");
Thread t3 = new Thread(mr1, "c");
t1.start();
t2.start();
t3.start();
}
}
이따구로는 하면 안되고 아래 예제를 봅시다
package day11;
class StaticLockPrint implements Runnable {
private static int i; //
static {
i = 5;
}
public void run() {
show();
}
public void show() {
synchronized (StaticLockPrint.class) {
//이렇게 막으면 먼저 들어온 애가 다 돌때까지는 접근 못함
for (; i < 100; i++) {
if (((Thread.currentThread()).getName()).equals("a")) {
System.out.print("[A" + i + "]");
} else if (((Thread.currentThread()).getName()).equals("b")) {
System.out.print("[B" + i + "]");
} else if (((Thread.currentThread()).getName()).equals("c")) {
System.out.print("[C" + i + "]");
}
}
} // synchronized
}
}
/*
* synchronized(StaticLockPrint.class){ for( ;i<100;i++){
* if(((Thread.currentThread()).getName()).equals("a") ){
* System.out.print("[A"+i+"]"); }else
* if(((Thread.currentThread()).getName()).equals("b") ){
* System.out.print("[B"+i+"]"); }else
* if(((Thread.currentThread()).getName()).equals("c") ){
* System.out.print("[C"+i+"]"); } } }
*/ ;
public class StaticLockPrintMain {
public static void main(String[] args) {
StaticLockPrint mr1 = new StaticLockPrint();
StaticLockPrint mr2 = new StaticLockPrint();
StaticLockPrint mr3 = new StaticLockPrint();
Thread t1 = new Thread(mr1, "a");
Thread t2 = new Thread(mr2, "b");
Thread t3 = new Thread(mr3, "c");
t1.start();
t2.start();
t3.start();
}
}
package day11;
class SleepThread extends Thread {
public SleepThread(String name) {
setName(name);
}
public void run() {
show();
}
public void show() {
for (int i = 0; i < 50; i++) {
print();
try {
Thread.sleep(50);// 50/1000 초
// sleep 들어가면 setPriority고 뭐고 그냥 반복됨
// 오래 점유하지 못함 -_-);;
} catch (InterruptedException ite) {
}
}
}
public void print() {
System.out.print(getName());// Thread에서
}
}
public class SleepThreadMain {
public static void main(String[] args) {
SleepThread t1 = new SleepThread("a");
SleepThread t2 = new SleepThread("b");
SleepThread t3 = new SleepThread("c");
t2.setPriority(7);// 1~10 클수록 우선순위
//기본 : 5
t1.start();// t2가 t1보다 우선이지만
try {
t1.join();// t1을 끝낸후 t2, t3를 실행한다.
// join(); 우선 내거 다 하고 - 다른 애들 기다림
} catch (InterruptedException ite) {
}
t2.start();
t3.start();
}
}
[03] 우선순위
- java.lang.MIN_PRIORITY, java.lang.NORM_PRIORITY, java.lang.MAX_PRIORITY
- setPriority(int p): 현재 스레드의 우선순위를 인자 p로 설정하기 위한 메소드
- getPriority(): 현재 스레드의 우선순위를 반환하는 메소드
1. sleep()를 적용한 경우
- 특정 스레드에 CPU의 자원이 집중하는 것을 막을 수 있다.
class RunThread2 extends Thread {
public RunThread2(String name) {
super(name);
}
public void run() {
for ( int i = 1; i <= 30000000 ; i++ ) {
if ( i % 50 == 0 ){
System.out.println("Thread [" + getName() + "] : " + i);
try{
//sleep(1); //0.001초
System.out.print("");
}catch(Exception e){ }
}
}
}
}
public class SchedulingTest2 {
public static void main(String args[]) {
Thread[] t = new RunThread2[5];
t[0] = new RunThread2("☆");
t[1] = new RunThread2("★");
t[2] = new RunThread2("◆");
t[3] = new RunThread2("◇");
t[4] = new RunThread2("○");
t[0].start();
t[1].start();
t[2].start();
t[3].start();
t[4].start();
}
}
2. 우선순위를 적용한 예
- Thread.MAX_PRIORITY 10
- Thread.NORM_PRIORITY 5
- Thread.MIN_PRIORITY 1
- sleep()의 이용, 우선순위가 적용은 되나 다른 스레드에게 제어권이 자주 넘어감
package day11;
class RunThread4 extends Thread {
public RunThread4(String name) {
super(name);
}
public void run() {
for (int i = 1; i <= 10000; i++) {
if (i % 50 == 0)
System.out.println("Thread [" + getName() + "] : " + i);
try {
sleep(1); // 0.001초
// 우선순위 해주든지 말든지 sleep 있으면
// 섞여서 나옴 ㅠㅠ... 강제로 재움..
} catch (InterruptedException e) {
}
}
}
}
public class SchedulingTest4 {
public static void main(String args[]) {
Thread[] t = new RunThread4[3];
t[0] = new RunThread4("☆");
t[1] = new RunThread4("◑");
t[2] = new RunThread4("○");
t[0].start();
t[0].setPriority(1);
t[1].start();
t[1].setPriority(5);
t[2].start();
t[2].setPriority(10);
//sleep 때문에 무쓸모됨 -_-
/*
* System.out.println("t[0]" + t[0].getPriority());
* System.out.println("t[1]" + t[1].getPriority());
* System.out.println("t[2]" + t[2].getPriority());
*/
}
}
------------------------------------------------------------------------------------
[23] NETWORK 이론및 관련클래스, Socket, ServerSocket의 이해 및 실습
1. Intranet / Internet의 구분
- 라우터를 기준으로 안쪽을 intranet, 외부를 Internet이라고 합니다.
그래서 학원 거 같은거슨 인트라넷
1) IP Address. . . . . : 172.16.203.31
- 접속 위치를 나타내는 프로토콜
- IP는 항구와 같은 위치 정보에 해당하며 컴퓨터를 구분하는 용도로 사용.
- Port는 항구에서 짐을 싫어 나르는 부두(port)와 같으며 네트워크로 접속되는 지점
- 하나의 IP에 할당된 여러개의 네트워크 프로그램을 구분하는 용도로 사용.
- 하나의 포트는 하나의 프로그램과 매핑(연결)됨
- IP 하나당 사용 가능한 포트 : 0 ~ 65535 (2Byte)
- 알려진 사용할 수 없는 포트
20, 21 : FTP, 파일 전송
22 : Secure Shell 접속
23 : Telnet, 원격 접속
25 : SMTP, 메일 전송
80 : HTTP, Apache, IIS등 웹서버, 인터넷 웹 페이지 서비스
3306 : MySQL 기본 포트, DBMS
1521 : Oracle 기본 포트, DBMS
8080 : Apache, 기타 웹 서버
1433 : MS-SQL 기본 포트, DBMS
- 1500번 이하는 시스템이 사용하는 포트가 많음으로 1500번 이상 사용을 권장함.
3. 네트워크를 지원하는 java.net 패키지의 기본클래스
- URL 클래스
. URL 클래스는 웹상에 존재하는 자원에 접근하거나 네트웍상의 유일한 주소를 나타내기 위한
방법을 제공하며, 또한 위치정보를 관리하기 위한 클래스 이다.
. 해당 위치에 스트림을 개설할 수 있다.(openStream() 이용)
- URL 객체 생성후 스트림 개설
URL객체를 생성할때는 MalformedURLException 에러처리를 해야 한다.
try{
URL uri = new URL("http", "hostname", 80, "default.htm");
InputStream is = uri.openStream();
}catch(MalformedURLException e){
e.printStackTrace();
}
호스트 이름: 얘는 고정아이피하고 연결이 되어져 있어서 네임서버가 도메인을 찾아줌 -_-)
http 를 통해서 서버에 요청함 -_-)
/**
URL 클래스를 이용하는 방법
**/
import java.net.*;
import java.io.*;
public class URLMain {
public static void main(String args[]) throws MalformedURLException, IOException {
URL url = new URL("http://www.bubblecat.co.kr"); // 인터넷 주소 객체
System.out.println("Port: " + url.getPort());
System.out.println("Protocol: " + url.getProtocol());
System.out.println("HostName: " + url.getHost());
System.out.println("File: " + url.getFile());
System.out.println("Ref: " + url.getRef());
String temp;
BufferedReader br;
br = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
//한글을 UTF-8 형식으로 변환 - 이거 안쓰면 한글 다 깨짐 -_-);;
while ((temp = br.readLine()) != null) {
System.out.println(temp);
}
br.close();
} // end of main
} // end of URLMain class
------------------------------------------------------------------------------------
: IP주소와 관련된 여러 정보 제공
InetAddress의 객체를 생성하기 위해 스태틱의 getByName()메소들 이용한다.
package day11;
import java.net.*;
class AddressTest {
public static void main(String args[]) throws UnknownHostException {
InetAddress address = InetAddress.getLocalHost();
// getLocalHost() 메소드는 static으로 선언된 클래스 메소드임
//getLocalHost()가 현재 컴퓨터에 대한 it주소나 기타등등 해줌...
System.out.println("로컬 컴퓨터의 이름 : " + address.getHostName());
System.out.println("로컬 컴퓨터의 IP 주소 : " + address.getHostAddress());
address = InetAddress.getByName("java.sun.com");
System.out.println("java.sun.com 도메인 이름과 IP 주소 : " + address);
InetAddress SW[] = InetAddress.getAllByName("naver.com");
for (int i = 0; i < SW.length; i++) {
System.out.println(SW[i]);
}
}
}
: URL을 목표지점으로 하는 네트웍 연결을 위한 작업을 수행함
- URL객체의 스트림 생성과 URLConnection 객체의 스트림 생성
: URL 객체
URL uri = new URL("http", "hostname", 80, "default.htm");
InputStream is = uri.openStream();
: URLConnection 객체
URL uri = URL("http", "hostname", 80, "default.htm");
URLConnection con = uri.openConnection();
InputStream is = uri.getInputStream();
또는
URL uri = URL("http", "hostname", 80, "default.htm");
URLConnection con = uri.openConnection();
con.setDoOutput(true); //스트림방향을 출력으로 설정
OutputStream os = uri.getOutputStream();
4. Socket, ServerSocket
- ServerSocket: 클라이언트보다 먼저 실행되어 클라이언트의 접속 요청을 기다리며,
클라이언트가 접속하면 양방향 통신을 할 수 있는 Socket . 객체를 생성한다
- Socket: 다른 Socket과 데이터를 송수신 한다.

ⓐ Server: ServerSocket 생성
ⓑ Server: 포트감시 시작, Client의 접속을 기다림
ⓒ Client: Socket 생성시에 인자 값으로 서버의 IP, PORT를 지정, 서버에 접속 요구
ⓓ Server: Client의 요구를 받아 Socket 객체 생성
ⓔ Server: 생성된 Socket 객체를 이용해 Client에게 데이터를 보냄
ⓕ Client: Socket객체로 데이터를 받고 필요한 데이터를 다시 서버로 전송함


------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
5. 수업
진도:
hw:
6. 할것
CSF100-AC
아 이걸로 사냐공ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
어짜피 구형으로 살 거면 큰거 사고 싶다
아니면 졸라 싸면 피넛으로 사고 싶다 !!!
는 생각
'Programming' 카테고리의 다른 글
160401: 15회차 (5) | 2016.04.01 |
---|---|
160329: 12회차 (3) | 2016.03.29 |
160325: 10회차 (0) | 2016.03.25 |
160324: 9회차 (2) | 2016.03.24 |
160323: 8회차 (1) | 2016.03.23 |