SourceCode
main.java
package j;
public class Main {
private static final int TICKET_NUM = 15; //티켓 개수 정의
public static void main(String[] args) {
Manager mgr = Manager.getTicketManager();
mgr.setTicketLimits(5); //최대 티켓 개수
UserThread[] user = new UserThread[TICKET_NUM];
for(int i = 0; i<TICKET_NUM; i++) {
user[i] = new UserThread((i + 1) + "-thread");
user[i].start(); //스레드 실행
}
for(int i = 0; i<TICKET_NUM; i++) {
try { //예외처리 부분
user[i].join();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
for(int i = 0; i< TICKET_NUM; i++) { //결과 출력 부분
if (user[i].getMyTicket().getTicketNum() != 0) //티켓 번호가 0번이 아니라면
System.out.println("Consumer" + i +" get ticket" + user[i].getMyTicket().getTicketNum()); //결과 출력
}
}
}
NormalTicket.java
package j;
public class NormalTicket implements Ticket{
private int num;
public NormalTicket(int num) {
this.num = num;
}
public int getTicketNum() {
return this.num;
}
}
NullTicket.java
package j;
//발행할 수 있는 티켓보다 많은 양의 티켓을 요구할경우 발행이 안되게함
public class NullTicket implements Ticket {
public int getTicketNum() {
return 0;
}
}
Ticket.java
package j;
interface Ticket{
public int getTicketNum();
}
Manager.java
package j;
public class Manager {
private static Manager mgr;
private int limits;// 발행할 수 있는 티켓 수량
private int count; //현재 발행되어 있는 티켓의 수량
private Manager() {
count = 0; //티켓 개수 초기화
}
//한개의 티켓 발행기를 만들고 임계구역을 만들기 위해 동기화
public synchronized static Manager getTicketManager() {
if(mgr == null) {
mgr = new Manager();
}
return mgr;
}
//최대 티켓 개수
public synchronized void setTicketLimits(int limits) {
this.limits = limits;
}
//발행된 티켓의 수량이 최대치에 도달했는지 확인
public synchronized Ticket getTicket() {
if(this.count < this.limits)
return new NormalTicket(++this.count);
return new NullTicket();
}
}
UserThread.java
package j;
public class UserThread extends Thread {
private Ticket myTicket;
public UserThread(String name) {
super(name);
}
public void run() { //스레드 실행 부분
Manager mgr = Manager.getTicketManager();
myTicket = mgr.getTicket();//티켓 구입 요청
}
public Ticket getMyTicket() {
return myTicket;
}
}
싱글턴 패턴을 사용 티켓 발행기에서 정해진 수량의 티켓을 발행 하다고 가정했을 경우 유저 번호에 따라 몇 번 티켓을 발행하였는지 알 수 있도록 하였습니다. 티켓마다 고유 번호가 있고 사용자가 몇 번 티켓을 발행했는지 알 수 있어 티켓의 관리가 수월합니다.
-----------------------------------------------------------
SourceCode
main.java
package t;
public class Main {
private static final int THREAD_NUM = 10; //최대 사용자 =10
public static void main(String[] args) {
UsersThread[] user = new UsersThread[THREAD_NUM];//생성
for(int i = 0; i < THREAD_NUM; i++) {//10명 까지 이용
user[i] = new UsersThread((i + 1) + "-thread");
user[i].start(); //스레드 시작
}
}
}
Printer.java
package t;
import java.util.Random;
public class Printer {
private boolean available = true;
public boolean isAvailable() {
return available;
}
public void print(String name) {
try {
Thread.sleep(new Random().nextInt(100));
System.out.println(name + "is using" + this.toString());
}catch(InterruptedException e) { //예외처리 부분
e.printStackTrace();
}
SetAvailable(true);
}
public void SetAvailable(boolean available) {
this.available = available;
}
}
UsersThread.java
package t;
public class UsersThread extends Thread {
private Printer myPrinter;
public UsersThread(String name) {
super(name);
}
public void run() { //스레드 실행 부분
Manager mgr = Manager.getPrinterManager();
myPrinter = mgr.getPrinter();
myPrinter.print(getName());
}
}
Manager.java
package t;
import java.util.ArrayList;
public class Manager {
private static Manager mgr = null; //프린터 관리자 초기화
//여러개의instance 사용을 위해 배열 생성
private ArrayList<Printer> MPrinters = new ArrayList<Printer>();
private Manager() {
//프린저 3개생성
MPrinters.add(new Printer()); //프린터1
MPrinters.add(new Printer()); //프린터2
MPrinters.add(new Printer()); //프린터3
}
//메소드 동기화
//다중 스레드 환경에서 동시에 여러 스레드가 getPrinter 메서드를 소유하는 객체에 접근하는 것을 방지하고
//결과적으로는 하나의 프린터 관리자를 생성한다.
public synchronized static Manager getPrinterManager() {
if(mgr == null) {
mgr = new Manager();
}
return mgr;
}
//반복문을 넣어 프린터 이용 가능 여부를 검사
//조건에 만족하고 사용할수 있는 프린터 할당
public synchronized Printer getPrinter() {
while (true) {
for(Printer printer:MPrinters){
if(printer.isAvailable()) {
//프린터 이용 가능 여부를 검사.
printer.SetAvailable(false);
return printer;
}
}
}
}
}
싱글턴 패턴으로 10명의 사용자 중 다른 사용자가 사용중이라면 다른 사용자의 접근을 막고 1명의 사용자한테 1개의 프린터가 할당되는 방법입니다.
'Java > DesignPattern' 카테고리의 다른 글
스트래티지 패턴(Strategy pattern) (0) | 2019.10.04 |
---|