多執行緒搶沙包遊戲

zhengbiyu發表於2024-05-25

幼兒園玩搶沙包遊戲,共計100個沙包,有10個小朋友(4男6女),男生每次拿3個沙包,女生每次拿2個沙包,如果剩餘的沙包不夠每次拿的數量,則遊戲停止,請用java多執行緒模擬上述遊戲過程。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 幼兒園玩搶沙包遊戲,共計100個沙包,有10個小朋友(4男6女),男生每次拿3個沙包,女生每次拿2個沙包,
 * 如果剩餘的沙包不夠每次拿的數量,則遊戲停止,請用java多執行緒模擬上述遊戲過程。
 */
public class SnatchingSandbags {

    private static volatile int total = 100;
    private static Lock l = new ReentrantLock();
    private static CountDownLatch countDownLatch = new CountDownLatch(10);
    public static void main(String[] args) {
        BoyRunLock boy = new BoyRunLock();
        GirlRunLock girl = new GirlRunLock();
        List<Thread> threadList= new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            threadList.add(new Thread(boy, "boy" + (i + 1)));
        }
        for (int i = 0; i < 6; i++) {
            threadList.add(new Thread(girl, "girl" + (i + 1)));
        }
        for (Thread thread : threadList) {
            thread.start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(total);
        //以下程式碼測試tryLock,可以看出tryLock能讓更多小朋友拿到沙袋
        total = 100;
        CountDownLatch countDownLatch = new CountDownLatch(10);
        BoyRun boyRun = new BoyRun();
        GirlRun girlRun = new GirlRun();
        threadList= new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            threadList.add(new Thread(boyRun, "boy" + (i + 1)));
        }
        for (int i = 0; i < 6; i++) {
            threadList.add(new Thread(girlRun, "girl" + (i + 1)));
        }
        for (Thread thread : threadList) {
            thread.start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(total);
    }

    static class BoyRun implements Runnable {

        @Override
        public void run() {
            while (total >= 3) {
                if (l.tryLock()) {
                    if (total >= 3) {
                        System.out.println("threadName:" + Thread.currentThread().getName() + "BoyRun current total:" + total + ",after total:" + (total -= 3));
                    }
                    l.unlock();
                }
            }
            System.out.println("BoyRun end");
            countDownLatch.countDown();
        }
    }

    static class BoyRunLock implements Runnable {

        @Override
        public void run() {
            while (total >= 3) {
                l.lock();
                if (total >= 3) {
                    System.out.println("threadName:" + Thread.currentThread().getName() + "BoyRun current total:" + total + ",after total:" + (total -= 3));
                }
                l.unlock();
            }
            System.out.println("BoyRun end");
            countDownLatch.countDown();
        }
    }

    static class GirlRun implements Runnable {

        @Override
        public void run() {
            while (total >= 2) {
                if (l.tryLock()) {
                    if (total >= 2) {
                        System.out.println("threadName:" + Thread.currentThread().getName() + "GirlRun current total:" + total + ",after total:" + (total -= 2));
                    }
                    l.unlock();
                }
            }
            System.out.println("GirlRun end");
            countDownLatch.countDown();
        }
    }

    static class GirlRunLock implements Runnable {

        @Override
        public void run() {
            while (total >= 2) {
                l.lock();
                if (total >= 2) {
                    System.out.println("threadName:" + Thread.currentThread().getName() + "GirlRun current total:" + total + ",after total:" + (total -= 2));
                }
                l.unlock();
            }
            System.out.println("GirlRun end");
            countDownLatch.countDown();
        }
    }
}

相關文章