gpt4 book ai didi

java - Java 中信号量的一般用途

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:11:32 24 4
gpt4 key购买 nike

该程序将生成 n-LIZARD 线程和 1 个 CAT 线程。“醒来”后,LIZARD 线程必须执行“吃”任务。蜥蜴必须从西米棕榈树穿越到猴草上才能“吃掉”,然后再穿越回去。 cat 线程将在给定时间后唤醒,然后检查以确保同时“交叉”的 LIZARD 线程不超过 4 个。这个想法是让“世界”或程序运行,直到 120 秒的给定时间过去,并保护蜥蜴免受猫的伤害。

我对信号量类知之甚少,想知道如何实现和放置互斥排除和常规信号量。使用 .acquire() 和 .release() 控制此程序中的线程。

我知道互斥只会获得一个线程(所以我想这可以用来控制猫线程(如果我错了请告诉我)

所以我的常规信号量必须保护“十字路口”。

我已经有了想法,我只是需要一些关于安置的帮助。我将所有内容都注释掉了,这样你们就可以清楚我正在尝试(失败)做什么:)

import java.util.ArrayList;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*/
public class LizardsSync
{
/*
* Set this to the number of seconds you want the lizard world to
* be simulated.
* Try 30 for development and 120 for more thorough testing.
*/
private static int WORLDEND = 120;

/*
* Number of lizard threads to create
*/
private static int NUM_LIZARDS =20;

/*
* Maximum lizards crossing at once before alerting cats
*/
private static int MAX_LIZARD_CROSSING = 4;

/*
* Maximum seconds for a lizard to sleep
*/
private static int MAX_LIZARD_SLEEP_TIME = 3;

/*
* Maximum seconds for a lizard to eat
*/
private static int MAX_LIZARD_EAT_TIME = 5;

/*
* Number of seconds it takes to cross the driveway
*/
private static int CROSS_TIME = 2;

/*
* Number of seconds for the cat to sleep.
*/
private static int MAX_CAT_SLEEP;

/*
* A counter that counts the number of lizzards crossing sago to monkey grass
*/
int numCrossingSago2MonkeyGrass = 0;

/*
* A counter that counts the number of lizzards crossing monkey grass to sago
*/
int numCrossingMonkeyGrass2Sago = 0;

/**
* A semaphore to protect the crossway.

*/
Semaphore semaphoreCrossway = new Semaphore(MAX_LIZARD_CROSSING);

/**
* A semaphore for mutual exclusion.
*/
Semaphore mutex = new Semaphore(1);

// on both semaphores, you can call acquire() or release()
/*
* Indicates if the world is still running.
*/
private static boolean running = true;

/*
* Indicates if you want to see debug information or not.
*/
private static boolean debug = true;


public void go()
{
ArrayList<Thread> allThreads = new ArrayList<Thread>();

// create all the lizzard threads
for (int i=0; i < NUM_LIZARDS; i++)
{ allThreads.add(new LizardThread(i) );
allThreads.get(i).start();
}
// create the cat thread
Thread CatThread = new CatThread();
CatThread.start();

// let the world run for a while
sleep (WORLDEND);

// terminate all threads
running = false;
// wait until all threads terminate by joining all of them
for (int i=0; i < NUM_LIZARDS; i++) {
try {
allThreads.get(i).join();
} catch (InterruptedException ex) {
System.err.println ("unable to join thread, " + ex.getMessage());
}
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// starts the program
new LizardsSync().go();
}

/**
* Models a cat thread.
*/
public class CatThread extends Thread {


/**
* @see java.lang.Runnable.
*/
@Override
public void run()
{
while (running) {


// sleep for a while
catSleep();
// check on lizzards

checkCrossway();

}
}

/**
* Puts cat thread to sleep for a random time.
*/
public void catSleep()
{
int sleepSeconds = 1 + (int)(Math.random()*MAX_CAT_SLEEP);

if (debug) {
System.out.println ("Cat is sleeping for " + sleepSeconds + " seconds.");
System.out.flush();
}
try {
sleep(sleepSeconds*1000);
} catch (InterruptedException ex) {
Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
}

if (debug) {
System.out.println ("Cat awakes.");
System.out.flush();
}
}

/**
* Simulates cat checking the crossway.
*/
public void checkCrossway()
{

if (numCrossingMonkeyGrass2Sago + numCrossingSago2MonkeyGrass > MAX_LIZARD_CROSSING) {
System.out.println ("The cat says yum!");
System.out.flush();
System.exit(-1);
}
}
}

/**
* Models a lizard thread.
*/
public class LizardThread extends Thread {

private int _id;

/**
* Creates a new lizard thread.
*
* @param id the id assigned to the lizard thread
*/
public LizardThread(int id)
{
_id = id;
}

/**
* @see java.lang.Runnable.
*/
@Override
public void run()
{

while (running) {
// sleep for a while in sago
lizardSleep();
// wait until safe to cross from sago to monkey grass
sagoToMonkeyIsSafe();
// cross path to monkey grass
crossedOverToMonkey();
// eat in the monkey grass
lizardEat();
// wait untill its safe to cross back to sago
monkeyToSagoIsSafe();
// cross from cross monkey grass to sage
crossMonkeyToSago();
}
}

/**
* This tests if it is safe to travel from sago to monkey.
*
*/
public void sagoToMonkeyIsSafe()
{

if (debug) {
System.out.println ("Lizard [" + _id + "] checks sago -> monkey grass.");
System.out.flush();
}



if (debug) {
System.out.println ("Lizard [" + _id + "] thinks sago -> monkey grass is safe.");
System.out.flush();
}


}

/**
* Indicates that lizard crossed over to monkey grass.
*/
public void crossedOverToMonkey()
{
if (debug) {
System.out.println ("Lizard [" + _id + "] made it to monkey grass.");
System.out.flush();
}

if (debug) {
System.out.println ("Lizard [" + _id + "] thinks monkey grass -> sago is safe.");
System.out.flush();

}
}


/**
* This tests if it is safe to travel from monkey to sago.
*/
public void monkeyToSagoIsSafe()
{

if (debug) {
System.out.println ("Lizard [" + _id + "] checks monkey grass -> sago.");
System.out.flush();
}



if (debug) {
System.out.println ("Lizard [" + _id + "] thinks monkey grass -> sago is safe.");
System.out.flush();

}
}

/**
* Indicates that lizard crossed over to sago.
*/
public void crossedOverToSago()
{
if (debug) {
System.out.println ("Lizard [" + _id + "] made it to sago.");
System.out.flush();
}

if (debug) {
System.out.println ("Lizard [" + _id + "] thinks sago -> monkey grass is safe.");
System.out.flush();
}
}
/**
* Indicates that lizard is crossing over from monkey to sago.
*/
void crossMonkeyToSago()
{
if (debug) {
System.out.println ("Lizard [" + _id + "] is crossing monkey grass to sago.");
System.out.flush();
}

numCrossingMonkeyGrass2Sago++;

// simulate walk
try {
sleep(CROSS_TIME*1000);
} catch (InterruptedException ex) {
Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
}

numCrossingMonkeyGrass2Sago--;
}

/**
* Indicates that lizard is crossing over from sago to monkey.
*/
void crossSagoToMonkey()
{

if (debug) {
System.out.println ("Lizard [" + _id + "] is crossing sago to monkey grass.");
System.out.flush();
}

numCrossingSago2MonkeyGrass++;

// simulate walk
try {
sleep(CROSS_TIME*1000);
} catch (InterruptedException ex) {
Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
}

numCrossingSago2MonkeyGrass--;
}


/**
* Puts lizard thread to sleep for a random amount of time.
*/
public void lizardSleep()
{
int sleepSeconds = 1 + (int)(Math.random()*MAX_LIZARD_SLEEP_TIME);

if (debug) {
System.out.println ("Lizard [" + _id + "] is sleeping for " + sleepSeconds + " seconds.");
System.out.flush();
}
try {
sleep(sleepSeconds*1000);
} catch (InterruptedException ex) {
Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
}
if (debug) {
System.out.println ("Lizard [" + _id + "] awakes.");
System.out.flush();
}
}

/**
* Simulates lizard eating for a random amount of time.
*/
public void lizardEat()
{
int eatSeconds = 1 + (int)(Math.random()*MAX_LIZARD_EAT_TIME);

if (debug) {
System.out.println ("Lizard [" + _id + "] is eating for " + eatSeconds + " seconds.");
System.out.flush();
}
try {
sleep(eatSeconds*1000);
} catch (InterruptedException ex) {
Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
}
if (debug) {
System.out.println ("Lizard [" + _id + "] finished eating.");
System.out.flush();
}
}
}


/**
* Puts current thread to sleep for a specified amount of time.
*
* @param seconds the number of seconds to put the thread to sleep
*/
private static void sleep(int seconds)
{
try {
Thread.sleep(seconds*1000);
} catch (InterruptedException ex) {
Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
}
}

}

最佳答案

每当你必须跨越路径时,你将调用acquire,而当你跨越路径时,你可以调用release

Semaphore semaphore= new Semaphore(No of Lizards that can cross the road at a time);


sagoToMonkeyIsSafe();<-- semaphore.acquire(); as crossing the path start
// cross path to monkey grass
crossedOverToMonkey();<---semaphore.release(); as crossing the path end

monkeyToSagoIsSafe();<-- semaphore.acquire(); as crossing the path start
// cross from cross monkey grass to sage
crossMonkeyToSago();<---semaphore.release(); as crossing the path end

关于java - Java 中信号量的一般用途,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13043182/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com