멀티 스레드
동시에 여러 작업을 병행하기 위해 다중의 스레드를 생성하여 운영하는 방식.
한개 이상의 스레드를 실행하면 실행결과가 섞여서 나오는데이때 순서를 정하는 방법으로
Round-Robin(순환할당) 방식과 Priority(우선순위) 방식이 있다.
아래의 예제에서는 setPriority()메소드를 사용하여 우선순위를 정하는 방식으로 스레드의 순서를 정해주었다.
우선순위가 높을수록 실행상태를 더 많이 가지게 된다.
*java.lang 패키지에 Thread클래스 있어 따로 import 해주지 않아도 된다(기본으로 포함됨)
import java.io.*;
public class MultiThread {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
System.out.println("실행시킬 단?");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int dan=Integer.parseInt(br.readLine());
GuGu gu=new GuGu(dan);
//생성자인수로 Runnable 객체 전달->Thread객체 생성
Thread t=new Thread(gu);
PrintThread pt=new PrintThread();
t.setPriority(10);//Thread.MAX_PRIORITY
pt.setPriority(Thread.MIN_PRIORITY);//1
t.start(); pt.start();
}
}
//Runnable 구현(Thread 상속 권장)
class GuGu implements Runnable{
private int dan;
public GuGu(int dan) {
this.dan= dan;
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=1;i<=9;i++) {
try {
Thread.sleep(1500);//1.5초
System.out.println(dan+"단:"+dan+"*"+i+"="+(dan*i));
}catch(InterruptedException e) {
System.out.println(e);
}
}//for
}
}
//Thread 상속
class PrintThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=1;i<=9;i++) {
try{
//난수(임의로 만드는 숫자)
long sleeptime=(int)Math.random()*500+1;//1~500
System.out.println("sleeptime="+sleeptime);
Thread.sleep(1500);//sleeptime
System.out.println("i="+i);
}
catch(Exception e) {e.printStackTrace();}
}
}
}
/*
실행시킬 단?
4
sleeptime=328
i=1
4단:4*1=4
...
i=7
sleeptime=60
4단:4*7=28
*/
스레드 동기화
한개 이상의 스레드가 하나의 데이터에 대한 작업을 할때
하나의 스레드가 먼저 일을 다 처리할 동안 다른 스레드는 대기상태로 유지할 수 있도록 해주는 기법
동기화 구현하는 방법
1. 메소드명 앞에 syhchronized 키워드를 붙여준다
메소드 자체에 동기화 설정
다른 스레드가 메소드 작업을 하고 있다면 종료할때까지 기다린 후 접근할 수 있다(락을 거는 개념)
import java.io.*;
public class ShareTest implements Runnable{
RandomAccessFile raf = null;
//Thread를 2개 생성한 후 실행
public ShareTest() {
try {
//경로 포함해서 생성할 파일명, 모드(r,rw)
//없으면 파일생성, 동일파일 있으면 덮어씀
raf= new RandomAccessFile("c:/webtest/3.java/result.txt","rw");
//Thread객체를 생성(Runnable객체, 쓰레드명)
Thread t1 = new Thread(this,"lys");
Thread t2 = new Thread(this,"test");
//Thread객체 실행
t1.start();
t2.start();
}catch(IOException e) {
System.out.println("파일생성에 오류발생=>"+e);
}
}
@Override
public synchronized void run() {
// TODO Auto-generated method stub
try {
for(int i=0;i<100;i++) {
raf.writeBytes(Thread.currentThread().getName()+
"["+i+"]"+raf.getFilePointer()+"\n");
}
}catch(Exception e) {
System.out.println("파일 데이터 출력오류=>"+e);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//Runnable객체 생성
new ShareTest();
}
}
*RandomAccessFile
특정위치에 접근해서 정해진 파일을 생성시켜주는 클래스
getFilePointer() : 파일 포인터위치를 확인할 수 있다
writeBytes(String s) : 파일에 String문자열이 출력된다
동기화 전(synchronized 붙이기 전)
작업 순서를 지키지 않고 실행된다
동기화 후
lys 스레드의 start() 작업이 끝난 후 test 스레드가 실행된다
2. 메소드 내부에 synchronized 키워드를 이용해서 특정 공유객체를 설정한다
한개 이상의 스레드가 동시에 특정 메소드에 접근은 할 수 있지만, 그 메소드의 특정 부분에는 동시 접근이 안된다
형식) synchronized(공유할데이터){ ,,, }
package j210125;
//급여통장(공유데이터) => ATM(쓰레드 작동)
class ATM implements Runnable{
private long money=10000;
@Override
public void run() {//자동이체
// TODO Auto-generated method stub
synchronized(this) {//ATM객체
for(int i=0;i<3;i++) {
try {
Thread.sleep(1000);//1초간격
}catch(Exception e) {}
if(getMoney()<=0)//if(money<=0)
break;
withDraw(2000);
}//3번을 실시간으로 인출해가는 과정을 보여주기 위함
}
}
//돈을 인출
public void withDraw(long howmuch) {
if(money>0) {
money-=howmuch;
System.out.println(Thread.currentThread().getName()+","+getMoney());
}else {
System.out.println("잔액이 부족합니다");
}
}
//잔액 조회
public long getMoney() {
return this.money;
}
}
public class SyncTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
ATM atm = new ATM();
Thread t1 = new Thread(atm,"보험금"); //Runnable객체, 쓰레드이름
Thread t2 = new Thread(atm,"공과금");
t1.start(); t2.start(); //-> run()-> withDraw()
}
}
/*
보험금,8000
보험금,6000
보험금,4000
공과금,2000
공과금,0
*/
'JAVA' 카테고리의 다른 글
[JAVA]자바 싱글톤패턴 예시 (0) | 2021.06.25 |
---|---|
[JAVA]네트워크, 프로토콜, properties 객체 (0) | 2021.06.25 |
[JAVA] 프로세스, 스레드 개념, 스레드 메소드 start() run() (0) | 2021.06.23 |
[JAVA] 제너릭 <?> <? extends T> <? super T> (0) | 2021.06.22 |
[JAVA] 인터페이스 객체 생성하는 3가지 방법 (0) | 2021.06.22 |