Vous pouvez obtenir les résultats souhaités en utilisant la méthode concurrente de java util. SynchronousQueue . Créez un nombre fixe de travailleurs. Utilisez le prendre pour lancer la lecture du bloc sur la SynchronousQueue. Ainsi, si tous les travailleurs ont pris un travail chacun et sont occupés à les traiter (en communiquant avec le socket), il n'y aura pas de lecture de la SynchronousQueue et donc un appel de type offre vers la file d'attente synchrone échouera. En vérifiant cet échec (ce qui signifie que tous les travailleurs à nombre fixe sont occupés, aucun ne s'accroche à la file d'attente maintenant), rejeter la ou les demandes suivantes.
Exemple de code dans les lignes suivantes [Non testé - Les exceptions ont été évitées pour des raisons de brièveté, veuillez les modifier selon vos besoins].
public class BoundedServer
{
public static void main(String[] args)
{
/**
* Port to serve
*/
final int port = 2013;
/**
* Max Workers
*/
final int maxworkers = 10;
/**
* The server socket.
*/
ServerSocket mServerSocket = null;
/**
* Queue of work units to process if there is a worker available.
*/
final SynchronousQueue<WorkUnit> mQueueToProcess = new SynchronousQueue<WorkUnit>();
/**
* Queue of work units to reject if there is no current worker available.
*/
final LinkedBlockingQueue<WorkUnit> mQueueToReject = new LinkedBlockingQueue<WorkUnit>();
/**
* A thread pool to handle the work.
*/
final ExecutorService communicationservice = Executors.newFixedThreadPool(maxworkers);
/**
* Let a single thread take care of rejecting the requests when needed to do so.
*/
final ExecutorService rejectionservice = Executors.newSingleThreadExecutor();
try
{
Runnable communicationlauncher = new Runnable()
{
public void run()
{
try
{
/**
* Set of workers to handle the work.
*/
final CommunicationWorker[] workers = new CommunicationWorker[maxworkers];
communicationservice.invokeAll(Arrays.asList(workers));
}
finally
{
communicationservice.shutdown();
}
}
};
new Thread(communicationlauncher).start();
Runnable rejectionlauncher = new Runnable()
{
public void run()
{
try
{
RejectionWorker rejectionworker = new RejectionWorker(mQueueToReject);
rejectionservice.submit(rejectionworker);
}
finally
{
rejectionservice.shutdown();
}
}
};
new Thread(rejectionlauncher).start();
mServerSocket = new ServerSocket(port);
while(true)
{
WorkUnit work = new WorkUnit(mServerSocket.accept());
if(!mQueueToProcess.offer(work))
{
mQueueToReject.add(work);
}
}
}
finally
{
try
{
mServerSocket.close();
}
}
}
}
public class WorkUnit
{
private Socket mSocket = null;
public WorkUnit(Socket socket)
{
super();
this.setSocket(socket);
}
public Socket getSocket() {
return mSocket;
}
public void setSocket(Socket mSocket) {
this.mSocket = mSocket;
}
}
public class CommunicationWorker
implements Callable<Boolean>
{
private SynchronousQueue<WorkUnit> mQueueToProcess;
public CommunicationWorker(SynchronousQueue<WorkUnit> queueToProcess)
{
super();
this.mQueueToProcess = queueToProcess;
}
@Override
public Boolean call() throws Exception
{
while(true)
{
WorkUnit work = mQueueToProcess.take();
Socket socket = work.getSocket();
// Code to handle socket communication and closure.
// Once the communication is finished, this thread will get blocked to mQueueToProcess.
}
}
}
public class RejectionWorker
implements Callable<Boolean>
{
private LinkedBlockingQueue<WorkUnit> mQueueToReject;
public RejectionWorker(LinkedBlockingQueue<WorkUnit> queueToReject)
{
super();
this.mQueueToReject = queueToReject;
}
@Override
public Boolean call() throws Exception
{
while(true)
{
WorkUnit work = mQueueToReject.take();
Socket socket = work.getSocket();
// Code to reject the request.
}
}
}