スレッドどうしで対戦する2人専用じゃんけんゲーム with Java

###【概要】
2スレッドを生成し、そのスレッドどうしでじゃんけんをして結果を表示します。
GitHubにアップしてあります　→　[threadJankenGame](https://github.com/nobu1234/threadJankenGame)

###【コード】
```java:JankenCallable.java
package game;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import game.Janken.Hand;

public class JankenCallable implements Callable<Janken.Hand> {

	public static int playerNumber = 1;
	public final static Object lock = new Object();

	@Override
	public Hand call() throws Exception {
		TimeUnit.SECONDS.sleep(1);

		synchronized (lock) {
			playerNumber++;

			if (playerNumber % 2 == 0) {
				System.out.println("1人目の名前 ： " + Thread.currentThread().getName());
			} else {
				System.out.println("2人目の名前 ： " + Thread.currentThread().getName());
			}
		}

		return Janken.getHand();
	}
}
```

```java:Janken.java
package game;

public class Janken {
	public enum Hand {
		GUU("グー"), CHOKI("チョキ"), PAA("パー");

		private final String hand;

		private Hand(String hand) {
			this.hand = hand;
		}

		public String getHand() {
			return hand;
		}
	}

	/**
	 * じゃんけんの結果を表示する
	 *
	 * @param firstPlayerHand
	 *            1人目の出した手
	 * @param secondPlayerHand
	 *            2人目の出した手
	 */
	public static void getGameResult(Hand firstPlayerHand, Hand secondPlayerHand) {
		// じゃんけんの勝者を1人目と仮置きする
		Hand winner = firstPlayerHand;

		if (firstPlayerHand == Hand.GUU && secondPlayerHand == Hand.PAA) {
			winner = secondPlayerHand;
		} else if (firstPlayerHand == Hand.CHOKI && secondPlayerHand == Hand.GUU) {
			winner = secondPlayerHand;
		} else if (firstPlayerHand == Hand.PAA && secondPlayerHand == Hand.CHOKI) {
			winner = secondPlayerHand;
		}

		System.out.println(getPlayerHand(firstPlayerHand, secondPlayerHand));
		if (firstPlayerHand == secondPlayerHand) {
			System.out.println("あいこです。");
		} else if (winner == firstPlayerHand) {
			System.out.println("1人目の勝ちです。");
		} else if (winner == secondPlayerHand) {
			System.out.println("2人目の勝ちです。");
		}
		System.out.println("");
	}

	/**
	 * ランダムにじゃんけんの手を取得する
	 * @return じゃんけんの手
	 */
	public static Hand getHand() {
		double random = Math.random() * 10;
		if (6.6 < random) {
			return Hand.GUU;
		} else if (3.3 < random) {
			return Hand.CHOKI;
		}
		return Hand.PAA;
	}

	/**
	 * プレイヤーが出した手を表示する
	 *
	 * @param firstPlayerHand
	 *            1人目の出した手
	 * @param secondPlayerHand
	 *            2人目の出した手
	 * @return 1人目と2人目の手の出し方
	 */
	private static String getPlayerHand(Hand firstPlayerHand, Hand secondPlayerHand) {
		return "1人目の手は" + String.format("%s", firstPlayerHand.getHand()) + " ：  2人目の手は"
				+ String.format("%s", secondPlayerHand.getHand());
	}

}
```

```java:Main.java
package game;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import game.Janken.Hand;

public class Main {

	// スレッドプール数　2人専用のじゃんけんゲームのため"2"限定となってしまう
	private static final int THREAD_POOL_COUNT = 2;
	// じゃんけんのゲーム回数
	private static final int GAME_COUNT = 3;

	public static void main(String[] args) {
		ExecutorService executorService = Executors.newScheduledThreadPool(THREAD_POOL_COUNT);

		List<Future<Hand>> jankenList = new ArrayList<>();
		for (int i = 0; i < GAME_COUNT * 2; i++) {
			Future<Hand> future = executorService.submit(new JankenCallable());
			jankenList.add(future);
		}

		int count = 0;
		Hand firstPlayerHand = null;
		Hand currentPlayerHand = null;
		for (Future<Hand> hand : jankenList) {
			count++;

			try {
				currentPlayerHand = hand.get();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			} finally {
				executorService.shutdown();
			}

			// 1人目と2人目の手が決まったところで結果を表示する
			if (count % THREAD_POOL_COUNT == 0) {
				Janken.getGameResult(firstPlayerHand, currentPlayerHand);
			} else {
				firstPlayerHand = currentPlayerHand;
			}
		}
	}
}
```

###【実行例】
```text
1人目の名前 ： pool-1-thread-1
2人目の名前 ： pool-1-thread-2
1人目の手はグー ：  2人目の手はグー
あいこです。

1人目の名前 ： pool-1-thread-1
2人目の名前 ： pool-1-thread-2
1人目の手はグー ：  2人目の手はパー
2人目の勝ちです。

1人目の名前 ： pool-1-thread-2
2人目の名前 ： pool-1-thread-1
1人目の手はパー ：  2人目の手はグー
1人目の勝ちです。
```

###【参考】
[ExecutorServiceを使って、Javaでマルチスレッド処理](https://qiita.com/mmmm/items/f33b757119fc4dbd6aa1)
[synchronizedブロックに使用されているStaticObjectが変更される場合、実質synchronizedされていない](http://garapon.hatenablog.com/entry/20091103/1257219569)

###【問題点・改善点】
・3人(3スレッド)以上ではじゃんけんゲームができない。
・結果のコロン(：)の位置を揃えたかった。

###【おまけのコーナー】
スレッド処理は難しい。