Java Semaphore基于线程值获取订单

时间:2015-07-12 16:12:25

标签: java multithreading semaphore

大家下午好,

我正在开展一个学校项目,要求我使用信号量来控制对资源的访问。根据我迄今为止开发的内容,它们是:

信号量1)等候区 - 这只允许15个客户(线程)进入等候区,否则他们将被拒绝从商店(使用TryAcquire)。

信号量2) ServerQueue - 这允许客户(线程)在等候区域中使用餐厅中仅有的3台服务器。

我的问题:我们的教授要求serverQueue在waitingArea中采用最短顺序(IE,具有最少burritosOrdered的线程)。

完整的申请流程:

  • 主要方法实例化serverQueue(3台服务器)和waitingArea(15位客户)
  • 主要方法实例化并启动20个客户线程
  • 已覆盖每个客户(线程)运行功能以尝试进入等候区域
  • waitingArea中的每个客户都尝试访问serverQueue
  • 中的服务器

如何告诉serverQueue获取最短订单?因为线程覆盖了运行,所以我没有直接访问所有线程的数组来比较它们的值。

感谢您一起来看看!

主要

public class Main {

    private static final int numCustomers = 5;

    public static void main(String[] args)
    {
        ServerQueue serverQueue = new ServerQueue();
        WaitingArea waitingArea = new WaitingArea(3, serverQueue);
        Thread customers[] = new Thread[numCustomers];

        for (int i = 0; i < numCustomers; i++)
        {
            customers[i] = new Thread(new Customer(waitingArea), "Customer " + i);
        }

        for (int i = 0; i < numCustomers; i++)
        {
            customers[i].start();
        }
    }
}

客户

import java.util.Date;
import java.util.Random;

// Runnable is an interface that facilitates threads
public class Customer implements Runnable {

    // The semaphore
//    private ServerQueue serverQueue;
    private WaitingArea waitingArea;
    public int burritosOrdered;
    public int burritosMade = 0;

    // Constructor, allow semaphore to be passed/assigned
    public Customer(WaitingArea waitingArea) {
        this.waitingArea = waitingArea;
        Random r = new Random();
        this.burritosOrdered = r.nextInt(21);
    }

    public void setBurritosMade(int newBurritos) {
        this.burritosMade += newBurritos;
    }

    // We must override the run function within Runnable
    // The run function is called by threadObject.start();
    @Override
    public void run() {
        waitingArea.seatCustomer(burritosOrdered);
    }
}

waitingArea

import java.util.Date;
import java.util.concurrent.Semaphore;

public class WaitingArea {

    private Semaphore semaphore;
    private ServerQueue serverQueue;
    private int maxCustomers;

    public WaitingArea(int maxCustomers, ServerQueue serverQueue) {
        semaphore = new Semaphore(maxCustomers, true);
        this.serverQueue = serverQueue;
        this.maxCustomers = maxCustomers; 
    }

    public void seatCustomer(int burritosOrdered)
    {
        boolean hasPermit = false;

        try
        {
            hasPermit = semaphore.tryAcquire();
            if(hasPermit) {
                System.out.println(new Date() + " - " 
                    + Thread.currentThread().getName() 
                    + " entered store ordering " 
                    + burritosOrdered + " burritos");
                serverQueue.finishOrder();
            } else {
                System.out.println(new Date() + " - " + Thread.currentThread().getName() + " left due to full shop");
            }

        } catch (InterruptedException e) {
           e.printStackTrace();
        } finally {   

            if(hasPermit) {
                semaphore.release();
                System.out.println(new Date() + " - " 
                    + Thread.currentThread().getName() 
                    + " left with " + burritosOrdered + " burritos made");
            }
        }
    }

}

serverQueue

import java.util.Date;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class ServerQueue {
    // This Semaphore will keep track of no. of servers used at any point.
    private final Semaphore semaphore;

    // While checking/acquiring a free server out of three available servers, we will use this lock.
    private final Lock serverLock;

    // This array represents the pool of free server.
    private boolean freeServers[];

    public ServerQueue() {
        semaphore = new Semaphore(1, true);
        freeServers = new boolean[1];
        serverLock = new ReentrantLock();

        // Set all servers to available
        for(int i=0;i<freeServers.length;i++) {
            freeServers[i] = true;
        }
    }

    public void finishOrder() throws InterruptedException {
        try {
            System.out.println(semaphore.getClass());
            // Decrease the semaphore counter to mark a printer busy
            semaphore.acquire();

            // Get the server printer
            int assignedServer = getServer();
            Thread.sleep(3000);
            // Print the job
            System.out.println(new Date() + " - " + Thread.currentThread().getName() 
                    + " is getting service from server " + assignedServer);

            //Server is done; Free the server to be used by other threads.
            releaseServer(assignedServer);

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.print(new Date() + " - " + Thread.currentThread().getName() + " has been served\n");

            //Increase the semaphore counter back
            semaphore.release();
        }
    }

    //Acquire a free server to finish a job
    private int getServer() {

        int foundServer = -1;
        try {
            //Get a lock here so that only one thread can go beyond this at a time
            serverLock.lock();

            //Check which server is free
            for (int i=0; i<freeServers.length; i++)
            {
                //If free server found then mark it busy
                if (freeServers[i])
                {
                    foundServer = i;
                    freeServers[i] = false;
                    break;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //Allow other threads to check for free servers
            serverLock.unlock();
        }
        return foundServer;
    }

    //Release the server
    private void releaseServer(int i) {
        serverLock.lock();

        //Mark the server as free
        freeServers[i] = true;
        serverLock.unlock();
    }
}

SemaphoreSS

0 个答案:

没有答案