如何防止java中的线程饥饿

时间:2016-12-15 18:11:32

标签: java multithreading semaphore

我有书面程序解决了以下问题,但我试图让它免费STARVATION但我不知道如何实现它。因此,每个北方农民和南方农民都有相同的机会过桥。

方案 一条单车道桥梁连接北滕布里奇和南滕布里奇的两个佛蒙特州村庄。两个村庄的农民使用这座桥将产品运送到邻近的城镇。如果一个北行和南行的农民同时上桥,那么这座桥就会陷入僵局(佛蒙特州的农民很顽固,无法支援。)

在这里我尝试过:

package threading.practice;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SingleLaneBridge {

    public static void main(String[] args) 
    {
        final Bridge bridge = new Bridge();

        Thread thNorthbound = new Thread( new Runnable() {

            @Override
            public void run() {

                while(true)
                {
                    Farmer farmer = new Farmer(bridge);
                    Thread th = new Thread(farmer);
                    farmer.setName("North Farmer : "+th.getId());
                    th.start();
                    try
                    {
                        TimeUnit.SECONDS.sleep((long)(Math.random()*10));
                    }
                    catch(InterruptedException iex)
                    {
                        iex.printStackTrace();
                    }
                }

            }
        });

        Thread thSouthbound = new Thread( new Runnable() {

            @Override
            public void run() {

                while(true)
                {
                    Farmer farmer = new Farmer(bridge);
                    Thread th = new Thread(farmer);
                    farmer.setName("South Farmer : "+th.getId());
                    th.start();
                    try
                    {
                        TimeUnit.SECONDS.sleep((long)(Math.random()*10));
                    }
                    catch(InterruptedException iex)
                    {
                        iex.printStackTrace();
                    }
                }
            }
        });

        thNorthbound.start();
        thSouthbound.start();
    }

}

class Bridge
{
    private final Semaphore semaphore;

    public Bridge()
    {
        semaphore = new Semaphore(1);
    }
    public void crossBridge(Farmer farmer)
    {
        try
        {
            System.out.printf("Farmer %s is trying to cross the bridge.\n",farmer.getName());
            semaphore.acquire();
            System.out.printf("Farmer %s is crossing the bridge.\n",farmer.getName());
            long duration = (long)(Math.random() * 10);
            TimeUnit.SECONDS.sleep(duration);
        }
        catch(InterruptedException iex)
        {
            iex.printStackTrace();
        }
        finally
        {
            System.out.printf("Farmer %s has crossed the bridge.\n",farmer.getName());
            semaphore.release();
        }
    }
}

class Farmer implements Runnable
{
    private String name;
    private Bridge bridge;

    public Farmer(Bridge bridge)
    {
        this.bridge = bridge;
    }

    public void run()
    {
        bridge.crossBridge(this);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

1 个答案:

答案 0 :(得分:0)

java.util.concurrent.Semaphore有一个constructor that takes a fairness flag。设置此值时,队列将获取并保证它们以fifo顺序执行。

该文件有关于旗帜使用的说明:

  

通常,用于控制资源访问的信号量应初始化为公平,以确保没有线程缺乏访问资源。当使用信号量进行其他类型的同步控制时,非公平排序的吞吐量优势往往超过公平性考虑。