请不要将以下问题视为重复问题..!
我开发了一个类,让多个线程按顺序运行,一次一个,按顺序运行。此类的claimAccess函数和发布Access函数之间的所有应用程序代码将一次仅在一个线程中执行。所有其他线程将在队列中等待,直到前一个线程完成。现在请建议可以通过执行器,循环障碍或倒计时锁定等其他方式实现同样的事情。!!请建议如何通过其他方法构建
import java.util.ArrayList;
import java.util.List;
public class AccessGate {
protected boolean shouldWait = false;
protected final List waitThreadQueue = new ArrayList();
/**
* For a thread to determine if it should wait. It it is, the thread will
* wait until notified.
*
*/
public void claimAccess() {
final Thread thread = getWaitThread();
if (thread != null) {
// let the thread wait untill notified
synchronized (thread) {
try {
thread.wait();
} catch (InterruptedException exp) {
}
}
}
}
/**
* For a thread to determine if it should wait. It it is, the thread will be
* put into the waitThreadQueue to wait.
*
*/
private synchronized Thread getWaitThread() {
Thread thread = null;
if (shouldWait || !waitThreadQueue.isEmpty()) {
thread = Thread.currentThread();
waitThreadQueue.add(thread);
}
shouldWait = true;
return thread;
}
/**
* Release the thread in the first position of the waitThreadQueue.
*
*/
public synchronized void releaseAccess() {
if (waitThreadQueue.isEmpty()) {
shouldWait = false;
} else {
shouldWait = true;
// give the claimAccess function a little time to complete
try {
Thread.sleep(10);
} catch (InterruptedException exp) {
}
// release the waiting thread
final Thread thread = (Thread) waitThreadQueue.remove(0);
synchronized (thread) {
thread.notifyAll();
}
}
}
}
答案 0 :(得分:2)
这是通过ExecutorService
Executors.singleThreadExecutor()将一次执行一项任务,并按顺序执行。
创建一个使用单个工作线程运行的
Executor
无界队列。 (但请注意,如果此单个线程终止 由于在关机之前执行期间出现故障,新的将会 如果需要执行后续任务,取而代之。)任务是 保证执行顺序,并且不会超过一个任务 在任何特定时间都有效。
答案 1 :(得分:2)
是的,有更简单的方法可以做到这一点。最简单的就是使用显示器,无需等待,睡觉或任何其他恶作剧:
// somewhere visible
public final Object accessGate = new Object();
// in your application code
synchronized (accessGate) {
// this block will be executed only in one thread at one time
}
Java的内置监视器提供了您所需的语义。唯一的问题是无法保证线程获得锁定的顺序;这取决于底层操作系统如何处理锁定(信号量或互斥量或其他)的排序。操作系统可以很好地保证您需要的行为,但这通常不是便携式的。
如果您需要便携式订购保证,您可以选择一些。最明显的是公平性设为真的ReentrantLock
:
// somewhere visible
public final Lock accessGate = new ReentrantLock(true);
// in your application code
accessGate.lock();
try {
// this block will be executed only in one thread at one time
}
finally {
accessGate.unlock();
}
另一个是Semaphore
,其中一个许可和公平设置为真:
// somewhere visible
public final Semaphore accessGate = new Semaphore(1, true);
// in your application code
accessGate.acquire();
try {
// this block will be executed only in one thread at one time
}
finally {
accessGate.release();
}
这两个行为非常相似。