import javax.swing.plaf.TableHeaderUI; import java.awt.geom.AffineTransform; import java.lang.invoke.SwitchPoint; import java.util.concurrent.Semaphore; import java.util.*; public class Vinegar { public static void main(String args[]) throws InterruptedException{ init(); HashSet threads = new HashSet<>(); for (int i = 0; i < 20; i++) { threads.add(new C()); threads.add(new H()); threads.add(new H()); threads.add(new O()); } for(int i = 0; i < 20; i++) { threads.add(new H()); } // run all threads in background for(Thread t : threads) { t.start(); } for(Thread t : threads) { t.join(2000); } for(Thread t : threads) { if(t.isAlive()) { System.out.println("Possible deadlock!"); return; } } // after all of them are started, wait each of them to finish for maximum 2_000 ms // for each thread, terminate it if it is not finished System.out.println("Process finished."); } static Semaphore c; static Semaphore h; static Semaphore o; static Semaphore c_created; static Semaphore h_created; static Semaphore o_created; static Semaphore boss; private static void init() { c = new Semaphore(2); h = new Semaphore(4); o = new Semaphore(2); c_created = new Semaphore(0); h_created = new Semaphore(0); o_created = new Semaphore(0); boss = new Semaphore(0); } static class C extends Thread { private void excecute() throws InterruptedException { // at most 2 atoms should print this in parallel c.acquire(1); System.out.println("C here."); c_created.release(6); h_created.acquire(1); o_created.acquire(1); // after all atoms are present, they should start with the bonding process together System.out.println("Molecule bonding."); Thread.sleep(100);// this represent the bonding process boss.release(6); System.out.println("C done."); // only one atom should print the next line, representing that the molecule is created c.release(1); System.out.println("Molecule created."); } @Override public void run() { try { excecute(); } catch (InterruptedException e) { } } } static class H extends Thread { private void excecute() throws InterruptedException{ // at most 4 atoms should print this in parallel System.out.println("H here."); h.acquire(1); // after all atoms are present, they should start with the bonding process together c_created.acquire(1); h_created.release(4); o_created.acquire(1); System.out.println("Molecule bonding."); Thread.sleep(100);// this represent the bonding process boss.acquire(1); System.out.println("H done."); // only one atom should print the next line, representing that the molecule is created h.release(); System.out.println("Molecule created."); } @Override public void run() { try { excecute(); } catch (InterruptedException e) { } } } static class O extends Thread { private void excecute() throws InterruptedException{ // at most 2 atoms should print this in parallel o.acquire(1); System.out.println("O here."); // after all atoms are present, they should start with the bonding process together c_created.acquire(1); h_created.acquire(1); o_created.release(6); System.out.println("Molecule bonding."); Thread.sleep(100);// this represent the bonding process boss.acquire(1); System.out.println("O done."); // only one atom should print the next line, representing that the molecule is created o.release(1); System.out.println("Molecule created."); } @Override public void run() { try { excecute(); } catch (InterruptedException e) { } } } }