blob: 80133bffe33897bfa57491e6822b6aa312c2f2b7 [file] [log] [blame]
/*
* Copyright (c) 2008, 2010-2012 Eike Stepper (Berlin, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.net4j.util.concurrent;
import org.eclipse.net4j.internal.util.bundle.OM;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
/**
* @author Eike Stepper
* @deprecated As of 3.6 use {@link ExecutorWorkSerializer}.
*/
@Deprecated
public class AsynchronousWorkSerializer implements IWorkSerializer, IExecutorServiceProvider, Runnable
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_CONCURRENCY, AsynchronousWorkSerializer.class);
private ExecutorService executorService;
private Queue<Runnable> workQueue;
private Occupation occupation = new Occupation();
// private Object newElementLock = new Object();
public AsynchronousWorkSerializer(ExecutorService executorService, Queue<Runnable> workQueue)
{
if (executorService == null)
{
throw new IllegalArgumentException("executorService == null"); //$NON-NLS-1$
}
this.executorService = executorService;
this.workQueue = workQueue;
}
public AsynchronousWorkSerializer(ExecutorService executorService)
{
this(executorService, new ConcurrentLinkedQueue<Runnable>());
}
public ExecutorService getExecutorService()
{
return executorService;
}
public boolean addWork(Runnable work)
{
// Need to be a block of execution. Cannot add when doing last check
// XXX synchronized (newElementLock)
{
workQueue.add(work);
// isOccupied can (and must) be called unsynchronized here
if (!occupation.isOccupied())
{
synchronized (occupation)
{
occupation.setOccupied(true);
}
if (TRACER.isEnabled())
{
TRACER.trace("Notifying executor service"); //$NON-NLS-1$
}
executorService.execute(this);
}
}
return true;
}
/**
* Executed in the context of the {@link #getExecutorService() executor service}.
* <p>
*/
public void run()
{
// XXX synchronized (occupation)
{
Runnable work;
// for (;;)
{
while (occupation.isOccupied() && (work = workQueue.poll()) != null)
{
try
{
work.run();
}
catch (RuntimeException ex)
{
if (TRACER.isEnabled())
{
TRACER.trace(ex);
}
}
}
// ConcurrencyUtil.sleep(500);
// Could put the sync in the while loop... but not efficient.
// Doing a last check to make sure that no one added something in the
// queue
// synchronized (newElementLock)
// {
// if (!occupation.isOccupied() || (work = workQueue.peek()) == null)
// {
// occupation.setOccupied(false);
// break;
// }
// }
}
}
}
public void dispose()
{
if (occupation.isOccupied())
{
occupation.setOccupied(false);
}
workQueue.clear();
workQueue = null;
executorService = null;
}
@Override
public String toString()
{
return AsynchronousWorkSerializer.class.getSimpleName();
}
/**
* @author Eike Stepper
*/
private static final class Occupation
{
private boolean occupied;
public boolean isOccupied()
{
return occupied;
}
public void setOccupied(boolean occupied)
{
this.occupied = occupied;
}
}
}