시현
- Trader가 공유 자원 GoldmanSachs 클래스에서 참조하여 자동으로 매도, 매수를 하는 프로그램. Trader 클래스에는 sell과 buy 스레드가 동시에 실행되며 매도, 매수를 진행함.
- 사려는 주식의 가치만큼 현금이 있으면 매수 가능.
- 팔려는 주식의 가치만금 현금이 있으면 매도 가능.
- 더 이상 매도, 매수할 주식, 현금이 없다면 거래 정보와 함께 프로그램 종료.
클래스 다이어그램

과정
1차 제작
- Asset 클래스가 삼성전자와 KRW에 상속하는 구조 제작.
- abstract을 이용한 추상화.
- 총 Asset을 반환하고 비중을 계산함.
public class Main { public static void main(String[] args) { //Tesla, Samsung, KRW, USD 인스턴스 생성 Asset[] asset = new Asset[] { new Tesla(), new Samsung(), new KRW(), new USD() }; //총 자산 계산 int totalAsset = 0; int stockSum = 0; int cashSum = 0; for (int i = 0; i < asset.length; i++) { totalAsset += asset[i].getTotalValue(); if (asset[i] instanceof Stock) { stockSum += asset[i].getTotalValue(); } else if (asset[i] instanceof Cash) { cashSum += asset[i].getTotalValue(); } asset[i].printInfo(); } //총 자산 출력 System.out.println("stockSum = " + stockSum); System.out.println("cashSum = " + cashSum); System.out.println("totalAsset = " + totalAsset); //주식, 현금 비중 계산 System.out.println("stockWeight = " + (stockSum / (float) totalAsset * 100) + "%"); System.out.println("cashkWeight = " + (cashSum / (float) totalAsset) * 100 + "%"); } }
//추상 클래스 상속 public abstract class Asset { public abstract int getTotalValue(); public abstract int getCount(); public abstract int getPrice(); public abstract void printInfo(); }
public class USD extends Cash { //가치, 보유 자산 입력 private int price = 1100; private int count = 15; @Override public int getCount() { return count; } @Override public int getPrice() { return price; } @Override public int getTotalValue() { return price * count; } @Override public void printInfo() { System.out .println(String.format("name = USD, price = %d, count = %d, total = %d", price, count, price * count)); } }
2차 제작
- Main 클래스에서 삼성전자와 KRW count 값을 받음(캡슐화).
- Seller와 Buyer 스레드 생성.
- 매도, 매수 규칙 생성.
public class Main { public static void main(String[] args) { //samsung, KRW 인스턴스 생성 Asset[] asset = new Asset[] { new Samsung(20), new KRW(1600000) }; //현황 출력 int totalAsset = 0; int stockSum = 0; int cashSum = 0; for (int i = 0; i < asset.length; i++) { totalAsset += asset[i].getTotalValue(); if (asset[i] instanceof Stock) { stockSum += asset[i].getTotalValue(); } else if (asset[i] instanceof Cash) { cashSum += asset[i].getTotalValue(); } asset[i].printInfo(); } System.out.println("stockSum = " + stockSum); System.out.println("cashSum = " + cashSum); System.out.println("totalAsset = " + totalAsset); //trader 스레드 생성 Thread cathieWoodThread = new Thread(new CathieWood((Stock) asset[0], (Cash) asset[1])); Thread michealBurryThread = new Thread(new MichaelBurry((Stock) asset[0], (Cash) asset[1])); //생성한 스레드 실행 cathieWoodThread.start(); michealBurryThread.start(); } }
public class USD extends Cash { private int price = 1100; private int count = 15; @Override public int getCount() { return count; } @Override public int getPrice() { return price; } @Override public int getTotalValue() { return price * count; } @Override public void printInfo() { System.out .println(String.format("name = USD, price = %d, count = %d, total = %d", price, count, price * count)); } }
import java.util.Random; public class CathieWood implements Runnable { Random random = new Random(); private Stock stock; private Cash cash; //캐시 우드 생성자 public CathieWood(Stock s, Cash c) { stock = s; cash = c; } //매수 public boolean buy() { int n = random.nextInt(10); if (cash.getTotalValue() >= stock.getPrice()) { cash.sell(n * stock.getPrice()); stock.buy(n); return true; } else { System.out.println("no money to buy"); return false; } } //출력 public void reportTrading() { System.out.println("---------CathieWood Trading Report---------"); cash.printInfo(); stock.printInfo(); } public void run() { while (buy()) { reportTrading(); } } }
3차 제작
- 멀티 스레드로 공유 자원 활용.
- 동기화.
- sleep() 메소드 추가.
import java.util.Random; public class GoldmanSachs { //랜덤 함수 선언 Random random = new Random(); //매도 매소드 수식 및 동기화 public synchronized boolean buy(Stock stock, Cash cash) { int n = random.nextInt(20); if (cash.getTotalValue() >= n * stock.getPrice() && stock.getCount() >= n) { cash.substract(n * stock.getPrice()); stock.add(n); System.out.println("매수 주문이 체결되었습니다."); printTradingInfo(stock, cash); return true; } else { System.out.println("주식을 매수할 수 없습니다."); return false; } } //매수 메소드 주식 및 동기화 public synchronized boolean sell(Stock stock, Cash cash) { int n = random.nextInt(20); if (stock.getCount() >= n && cash.getTotalValue() >= stock.getPrice() * n) { cash.add(n * stock.getPrice()); stock.substract(n); System.out.println("매도 주문이 체결되었습니다."); printTradingInfo(stock, cash); return true; } else { System.out.println("주식을 매도할 수 없습니다."); return false; } } //거래 결과 출력 public synchronized void printTradingInfo(Stock stock, Cash cash) { cash.printInfo(); stock.printInfo(); } }
public class Trader implements Runnable { private Stock stock; private Cash cash; private GoldmanSachs goldmanSachs; private boolean isBuyer; //트레이더 생성자 선언 public Trader(Stock stock, Cash cash, GoldmanSachs goldmanSachs, boolean isBuyer) { this.stock = stock; this.cash = cash; this.goldmanSachs = goldmanSachs; this.isBuyer = isBuyer; } //스레드 실행 public void run() { if (isBuyer) { while (goldmanSachs.buy(stock, cash)) { try { Thread.sleep(50); } catch (Exception exception) { exception.printStackTrace(); } } } else { while (goldmanSachs.sell(stock, cash)) { try { Thread.sleep(50); } catch (Exception exception) { exception.printStackTrace(); } } } } }
핵심 개념
추상화
추상화는 유저에게 세부사항 숨기고 중요한 정보만 보여주는 과정임.
- Abstract class: 객체를 만들 수 없는 제한된 클래스
- Abstract method : 추상화 클래스에서만 사용 가능. body가 존재하지 않음. body는 하위 클래스에 의해 제공됨.
멀티 스레드
멀티 스레드는 두 개 이상이 동시에 실행하며 각자의 임무를 수행할 수 있음. 자원 최적화 가능.

공유자원
- 공유 자원이란 여러 스레드가 동시에 접근 가능한 자원을 말함.
- 공유자원은 동기화를 사용하여 자원의 혼잡을 막을 수 있음(synchronized).
마치며
구조 설계가 가장 어려웠다. 과연 상속으로 하는 게 맞는지, 클래스의 책임과 메시지는 어떤 것으로 해야 하는지 헷갈려서 자꾸만 썼다 지우기를 반복했다. 그리고 개념을 알고 사용해도 다음 날이면 다시 헷갈리는 점도 힘들었다. 분명 예시를 보고 적용까지 했는데 설명을 하려 하면 말문이 막혔다. 자바에 대해 이해했다고 생각한 순간이 얼마 되지도 않는데 다시 모르겠다.
이번에 평소 관심 있었던 자동 매수, 매도 프로그램을 만들었다. 매수, 매도하는 수식은 생각보다 간단했는데 주가 변동이나 종목을 받아오는 부분에 표현이 없어 그런 것 같다. 아직 코드 한 줄 한 줄 작성하기조차 버겁다 보니 모르는 부분을 선뜻 도전하기 어렵다. 그래도 기회가 되면 증권사에서 제공하는 API를 받아 프로그램을 만들어보고 싶다.