
import java.util.concurrent.Semaphore;
/**
* Javaスモーカー問題を実装する
* https://./-/////-.ng
*
*
* @date 22:41
*/
public class Demo5 {
// +
static Semaphore offer1 = new Semaphore(0);
// +
static Semaphore offer2 = new Semaphore(0);
// +
static Semaphore offer3 = new Semaphore(0);
// 喫煙が完全かどうか
static Semaphore finish = new Semaphore(0);
// テーブルへの相互排他的アクセス
static Semaphore desk = new Semaphore(1);
// 3人の喫煙者が交代でタバコを吸う実装に使われる
static int i = 0;
public static void main(String[] args) {
for (int j = 0; j < 3; j++) {
Thread provider = new Thread(new Prodiver());
provider.setName("provider" + i);
provider.start();
Thread smoke1 = new Thread(new Smoke1());
smoke1.setName("smoke1:" + i);
smoke1.start();
Thread smoke2 = new Thread(new Smoke2());
smoke2.setName("smoke2:" + i);
smoke2.start();
Thread smoke3 = new Thread(new Smoke3());
smoke3.setName("smoke3:" + i);
smoke3.start();
}
}
static class Prodiver implements Runnable {
@Override
public void run() {
while (true) {
try{
// 重要なリソースにアクセスする
desk.acquire();
if (i == 0) {
offer1.release();
} else if (i == 1) {
offer2.release();
} else {
offer3.release();
}
i = (i + 1) % 3;
// 誰かがタバコを吸い終わるのを待つ
finish.acquire();
// 重要なリソースを解決する
desk.release();
Thread.sleep(100);
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
static class Smoke1 implements Runnable {
// 現在の喫煙者が何本タバコを吸ったか
static int num = 0;
@Override
public void run() {
while (true) {
// テーブルの上に1つの組み合わせがあることを確認する
try {
offer1.acquire();
num++;
System.out.println(Thread.currentThread().getName() + "Smoke1は最初の"+ num + "タバコ");
//
finish.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Smoke2 implements Runnable {
// 現在の喫煙者が何本タバコを吸ったか
static int num = 0;
@Override
public void run() {
while (true) {
// テーブルIIに組み合わせがあることを確認する
try {
offer2.acquire();
num++;
System.out.println(Thread.currentThread().getName() + "Smoke2は最初の"+ num + "タバコ");
//
finish.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Smoke3 implements Runnable {
// 現在の喫煙者が何本タバコを吸ったか
static int num = 0;
@Override
public void run() {
while (true) {
// テーブルの上に1つの組み合わせがあることを確認する
try {
offer3.acquire();
num++;
System.out.println(Thread.currentThread().getName() + "Smoke3は最初の"+ num + "タバコ");
//
finish.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}