Java에서 Thread를 구현하는 5-Step
- Thread 클래스를 상속받는 사용자 정의 클래스를 생성한다.
- Thread 클래스로부터 상속받은 public void run 메서드를 오버라이딩 한다.
- public void run 메서드 내에 병행처리 할 코드를 작성한다.
- 작성된 사용자 정의 클래스를 바탕으로 인스턴스를 생성한다.
- 생성된 인스턴스로부터 start() 메서드를 호출한다.
public class Exam_01 {
public static void main(String[] args) {
// Worker w = new Worker();
// Worker2 w2 = new Worker2();
// Worker3 w3 = new Worker3();
// w.start();
// w2.start();
// w3.start();
new Worker().start();
new Worker2().start();
new Worker3().start();
for(int i =0; i<=99; i++) {
System.out.print("%");
}
}
}
public class Worker extends Thread{
public void run() {
for(int i =0; i<=99; i++) {
System.out.print("+");
}
}
}
같은 변수를 여러 스레드가 처리하도록 하는 방법
- 파라미터를 넣으면 오버라이딩 안된다.
- 설사 넣어도 콜바이밸류로 실제 값이 변하지 않음(같은이름의 다른 지역변수)
- public static
- 스태틱 멤버필드는 클래스 멤버필드
class PlusTarget extends Thread{
public void run() {
while(true) {
Quiz_02.target++;
}
}
}
class MinusTarget extends Thread{
public void run() {
while(true) {
Quiz_02.target--;
}
}
}
public class Quiz_02 {
public static int target = 0;
public static void main(String[] args) {
// while(true) {
// target++;
// }
// while(true) { //Unreachable code : 위의 반복문에서 벗어날수 없으므로 도달할수 없는 코드
// target--;
// }
//파라미터를 넣으면 오버라이딩 안된다.설사 넣어도 콜바이밸류로 실제 값이 변하지 않음(같은이름의 다른 지역변수)
//public static
//스태틱 멤버필드는 클래스 멤버필드
new PlusTarget().start();
new MinusTarget().start();
while(true) {
System.out.println(target);
}
}
}
- static
- call by reference
- inner class 방식 , nested class 방식 : 클래스를 안에다
public class Quiz_02 {
public static void main(String[] args) {
int target=0;
// class A{ //1.내부에 선언
// }
// Thread th = new Thread(); //2.인스턴스는 있지만 오버라이드 안되어있음
Thread th = new Thread() { //3.Thread 클래스를 바탕으로 인스턴스를 만들건데 수정해서 만들것이다.
int a;
};
// th.a // .으로 접근 못함, 자바에서 스레드형식이 a를 갖고 있다고 보지는 않음
while(true) {
System.out.println(target);
}
}
}
에러발생
Local variable target defined in an enclosing scope must be final or effectively final
public class Quiz_02 {
public static void main(String[] args) {
int target=0;
Thread th = new Thread() {
public void run() {
target++; //Local variable target defined in an enclosing scope must be final or effectively final
}//지역변수 target은 상수이거나 상수와 동일한 상태여야 한다
};
while(true) {
System.out.println(target);
}
}
}
상수로 만들어도
The final local variable target cannot be assigned, since it is defined in an enclosing type
public class Quiz_02 {
public static void main(String[] args) {
final int target=0;
Thread th = new Thread() {
public void run() {
target++; //The final local variable target cannot be assigned, since it is defined in an enclosing type
}
};
while(true) {
System.out.println(target);
}
}
}
스테틱을 사용하지 않는 경우
변수는 상수가 아니면서 상수와 같이 존재하도록 멤버필드로 위치 시키기
public class Quiz_02 {
public int target=0; // 스테틱 매서드 내에서는 넌스테틱을 쓰지 못함, 콜되었을 때 인스턴스 호출될지 확신 못함
public void func() {
Thread th1 = new Thread() {
public void run() {
while(true) {
target++;
}
}
};
Thread th2 = new Thread() {
public void run() {
while(true) {
target--;
}
}
};
th1.start();
th2.start();
while(true) {
System.out.println(target);
}
}
public static void main(String[] args) {
new Quiz_02().func();
}
}
//callback 패턴
public class Quiz_02 {
public int target=0; // 스테틱 매서드 내에서는 넌스테틱을 쓰지 못함, 콜되었을 때 인스턴스 호출될지 확신 못함
public void func() {
new Thread() {
public void run() {
while(true) {
target++;
}
}
}.start(); //익명 inner 클래스
new Thread() {
public void run() {
while(true) {
target--;
}
}
}.start();
while(true) {
System.out.println(target);
}
}
public static void main(String[] args) {
new Quiz_02().func();
}
}
쌍방 채팅
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
public void func() {
try {
ServerSocket server = new ServerSocket(50000);
System.out.println("서버를 가동했습니다.");
Socket sock = server.accept();
System.out.println(sock.getInetAddress() + " 에서 연결"); //127.0.0.1
DataInputStream dis =
new DataInputStream(sock.getInputStream());
DataOutputStream dos =
new DataOutputStream(sock.getOutputStream());
new Thread() {
public void run() {
try {
while(true) {
Scanner sc = new Scanner(System.in);
dos.writeUTF(sc.nextLine());
dos.flush();
}
}catch(Exception e) {
e.printStackTrace();
}
}
}.start();
new Thread() {
public void run() {
try {
while(true) {
System.out.println(sock.getInetAddress()+" : "+dis.readUTF());
}
}catch(Exception e) {
e.printStackTrace();
}
}
}.start();
}catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args){
new Server().func();
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public void func() {
try {
Socket sock = new Socket("192.168.60.19", 50000); //127.0.0.1 //192.168.60.19
DataInputStream dis =
new DataInputStream(sock.getInputStream());
DataOutputStream dos =
new DataOutputStream(sock.getOutputStream());
new Thread() {
public void run() {
try {
while(true) {
Scanner sc = new Scanner(System.in);
dos.writeUTF(sc.nextLine());
dos.flush();
}
}catch(Exception e) {
e.printStackTrace();
}
}
}.start();
new Thread() {
public void run() {
try {
while(true) {
System.out.println(sock.getInetAddress()+" : "+dis.readUTF());
}
}catch(Exception e) {
e.printStackTrace();
}
}
}.start();
}catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args){
new Client().func();
}
}
값공유
1. 스태틱
2. call by reference
3. inner class : 코드가 짧을 때 클래스를 나누지 않고 그안에
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JOptionPane;
class WriteThread extends Thread{
private DataOutputStream dos;
public WriteThread(DataOutputStream dos) {
this.dos = dos;
}
public void run() {
while(true) {
try {
dos.writeUTF(JOptionPane.showInputDialog("메세지 입력"));
dos.flush();
}catch(Exception e) {
e.printStackTrace();
System.exit(0);
}
}
}
}
class ReadThread extends Thread{
private DataInputStream dis;
public ReadThread(DataInputStream dis) {
this.dis = dis;
}
public void run() {
while(true) {
try {
System.out.println(dis.readUTF());
}catch(Exception e) {
e.printStackTrace();
System.exit(0);
}
}
}
}
public class Server3 {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(20000);
Socket sock = server.accept();
DataInputStream dis = new DataInputStream(sock.getInputStream());
DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
WriteThread wt = new WriteThread(dos);
ReadThread rt = new ReadThread(dis);
wt.start();
rt.start();
}catch(Exception e) {
e.printStackTrace();
}
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import javax.swing.JOptionPane;
public class Client3 {
public static void main(String[] args) {
try {
Socket sock = new Socket("127.0.0.1",20000);
DataInputStream dis = new DataInputStream(sock.getInputStream());
DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
WriteThread wt = new WriteThread(dos);
ReadThread rt = new ReadThread(dis);
wt.start();
rt.start();
}catch(Exception e) {
e.printStackTrace();
}
}
}
다중 접속 메세지
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server2 {
public static void main(String[] args){
try {
ServerSocket server = new ServerSocket(20000);
while(true) {
Socket sock = server.accept();
new SocketThread(sock).start();
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
import java.net.Socket;
public class SocketThread extends Thread{
private Socket sock;
public SocketThread(Socket sock) {
this.sock =sock;
}
public void run() {
try {
System.out.println(sock.getInetAddress() + " 에서 연결");
Thread.sleep(3000);
}catch(Exception e){
}
}
}
import java.io.DataOutputStream;
import java.net.Socket;
import javax.swing.JOptionPane;
public class Client2 {
public static void main(String[] args) {
try {
Socket sock = new Socket("192.168.60.57", 20000);
while(true) {
DataOutputStream dos =
new DataOutputStream(sock.getOutputStream());
dos.writeUTF(JOptionPane.showInputDialog("메세지 입력"));
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.HashSet;
import java.util.Set;
//다대일 서비스 프로그램
public class Server4 {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(50000);
System.out.println("서버가 구동되었습니다.");
System.out.println("클라이언트 연결을 대기중입니다...");
while(true) {//여러명의 클라이이언트 받아서 쓰레드를 생성.소켓&스레드 공장
try {
Socket sock = server.accept();
new SocketThread(sock).start();
}catch(Exception e) {
}
}
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.HashSet;
import java.util.Set;
public class SocketThread extends Thread{
private Socket sock;
DataInputStream dis;
DataOutputStream dos;
public SocketThread(Socket sock) {
this.sock = sock;
}
public void run() {
System.out.println(sock.getInetAddress() + "에서 연결하였습니다.");
try {
dis = new DataInputStream(sock.getInputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
try {
dos = new DataOutputStream(sock.getOutputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
while(true) {
try {
dos.writeUTF("Time/lotto/wise 중 하나를 입력해주세요");
String msg = dis.readUTF();
//축약하면 안됨. 그러면 if문에서 아닐때 else if 문으로 가는데 그러면 2번 이상 utf를 받아야하고 클라이언트에서는 자신의 답을 듣기 위하여 몇번을 입력해야할지 모른다.
//if(msg.contentEquals(dis.readUTF())){
// }else if(msg.contentEquals(dis.readUTF())) {}
//매우 위험
if(msg.contentEquals("Time")) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy"+"년 " + "MM" + "월 " + "dd" + "일 " + "HH:mm:ss");
String strTime = sdf.format(System.currentTimeMillis());
dos.writeUTF("현재시간 : " + strTime);
}else if(msg.contentEquals("lotto")) {
Set<Integer> set = new HashSet<>();
while(set.size() < 7) {
set.add((int) (Math.random() *45+1));
}
String strLotto = set.toString();
dos.writeUTF("오늘의 로또 : " + strLotto);
}else if(msg.contentEquals("wise")) {
String[] wise = new String[] {"Seeing is believing.",
"Whatever you do, make it pay.",
"You will never know until you try.",
" No sweat, no sweet.",
"Let bygones be bygones."};
int index = (int)Math.random()*5;
String strWise = wise[index];
dos.writeUTF("오늘의 운세 : " + strWise);
}else {
dos.writeUTF("다시 입력해주세요.");
}
dos.flush();
}catch(Exception e){
}
}
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import javax.swing.JOptionPane;
public class Client4 {
public static void main(String[] args) {
try {
Socket sock = new Socket("192.168.60.28", 50000); //192.168.60.28 //127.0.0.1
DataInputStream dis = new DataInputStream(sock.getInputStream());
DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
while(true) {
System.out.println(dis.readUTF());
dos.writeUTF(JOptionPane.showInputDialog("입력창"));
dos.flush();
System.out.println(dis.readUTF());
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JOptionPane;
public class Server4 {
public static void main(String[] args) throws Exception { //실습하는 동안만 throws
ServerSocket server = new ServerSocket(50000);
System.out.println("서버가 구동되었습니다.");
while(true) {
try {
Socket sock = server.accept();//accept리턴값을 받을 변수 만들기
new TLWThread(sock).start();
}catch(Exception e) {
}
}
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.text.SimpleDateFormat;
public class TLWThread extends Thread {
private Socket sock;
DataInputStream dis;
DataOutputStream dos;
public TLWThread(Socket sock) {
this.sock = sock;
}
public void run() {
System.out.println(sock.getInetAddress() + " 에서 연결하였습니다.");///192.168.60.19 에서 연결하였습니다.
try {
dis = new DataInputStream(sock.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
try {
dos = new DataOutputStream(sock.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
while(true) {
try {
dos.writeUTF("time/lotto/wise 중 하나를 입력해주세요");
String msg = dis.readUTF(); // 축약시 if문 조건 넘어 갈때마다 값 입력 받아야함
if(msg.contentEquals("time")) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy년MM월dd일 hh시mm분ss초");
String strTime = sdf.format(System.currentTimeMillis());
dos.writeUTF("현재시간 : "+ strTime);
}else if(msg.contentEquals("lotto")) {
int[] lotto = new int[45];
for(int i=0; i<lotto.length; i++) {
lotto[i]=i+1;
}
for(int i =0; i< 500; i++) {
int x = (int)(Math.random()*45);
int y = (int)(Math.random()*45);
int tmp = lotto[x];
lotto[x] = lotto[y];
lotto[y] = tmp;
}
String printLt =
"("+lotto[0]+") ("+lotto[1]+") ("+lotto[2]+") ("+lotto[3]+") ("+lotto[4]+") ("+lotto[5]+")";
dos.writeUTF("로또번호 : "+printLt);
}else if(msg.contentEquals("wise")) {
String[] str =new String[] {
"To be conscious that you are ignorant is a great step to knowledge. -Benjamin Disraeli-",
"Paradise is where I am. -Voltaire-",
"You may be disappointed if you fail, but you are doomed if you don't try. -Beverly Sills-"
};
dos.writeUTF("오늘의명언 : "+str[(int)(Math.random()*3)]);
}else {
dos.writeUTF("입력값을 확인해 주세요");
}
dos.flush();
}catch(Exception e){
}
}
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import javax.swing.JOptionPane;
public class Client4 {
public static void main(String[] args) {
try {
Socket sock = new Socket("127.0.0.1", 50000); //192.168.60.28 //127.0.0.1
DataInputStream dis = new DataInputStream(sock.getInputStream());
DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
while(true) {
System.out.println(dis.readUTF());
dos.writeUTF(JOptionPane.showInputDialog("입력창"));
dos.flush();
System.out.println(dis.readUTF());
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
질의응답
import java.util.Scanner;
class A{
}
public class Temp {
public static void main(String[] args) {
A a = new A(); // 인스턴스의 주소를 담는다
System.out.println(a); //A@15db9742, 자바는 주소를 숨김, 그 대신에 고유값을 보여줌
System.out.println(a.toString());//암묵적문법,결과는 같은 문법
//.toString은 Object에서 상속받은 기능
//만드는 사람이 오버라이드를 어떻게 했느냐에 따라 달라짐
Scanner sc = new Scanner(System.in);
System.out.println(sc);
int[] arr = new int[3];
System.out.println(arr);
// List<Integer> li = new ArrayList;
}
}
'디지털 컨버전스 > JAVA' 카테고리의 다른 글
| [이미지업로드] 파일 업로드 (0) | 2020.05.20 |
|---|---|
| [응용 SW기초기술 활용] 2020-03-11 (0) | 2020.03.10 |
| [Java] review , File, 네트워크 - 채팅하기, 파일전송 (0) | 2020.03.09 |
| [Java] 로그인 예제 (0) | 2020.02.25 |
| [Java] List , Set, Map (0) | 2020.02.24 |