Java 关于不同的同步方法
请不要将下面的问题视为重复问题 我开发了一个类,可以让多个线程按顺序运行,一次一个。此类的claimeraccess函数和release Access函数之间的所有应用程序代码一次只能在一个线程中执行。所有其他线程将在队列中等待,直到上一个线程完成。现在,请告知是否可以通过其他方式实现同样的功能,如执行器、循环屏障或倒计时闩锁等。。!!请建议如何通过其他方法构建此功能Java 关于不同的同步方法,java,multithreading,executors,Java,Multithreading,Executors,请不要将下面的问题视为重复问题 我开发了一个类,可以让多个线程按顺序运行,一次一个。此类的claimeraccess函数和release Access函数之间的所有应用程序代码一次只能在一个线程中执行。所有其他线程将在队列中等待,直到上一个线程完成。现在,请告知是否可以通过其他方式实现同样的功能,如执行器、循环屏障或倒计时闩锁等。。!!请建议如何通过其他方法构建此功能 import java.util.ArrayList; import java.util.List; public class
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();
}
}
}
}
这是通过
ExecutorService
将一次执行一个任务,并按顺序执行
创建一个执行器
,该执行器使用一个工作线程在
无限队列。(但是请注意,如果此单线程终止
由于关机前执行过程中出现故障,将出现新的故障
如果需要执行后续任务,则替换它。)任务
保证按顺序执行,最多只能执行一项任务
在任何给定时间都处于活动状态
这是通过
ExecutorService
将一次执行一个任务,并按顺序执行
创建一个执行器
,该执行器使用一个工作线程在
无限队列。(但是请注意,如果此单线程终止
由于关机前执行过程中出现故障,将出现新的故障
如果需要执行后续任务,则替换它。)任务
保证按顺序执行,最多只能执行一项任务
在任何给定时间都处于活动状态
是的,有更简单的方法。最简单的方法是只使用显示器,没有等待、睡眠或任何其他恶作剧:
// 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的内置监视器提供了您所需要的语义。唯一的问题是线程持有锁的顺序不能保证;这取决于底层操作系统如何处理锁排序(信号量或互斥量或其他)。操作系统可以很好地保证您需要的行为,但这通常不是可移植的
如果您需要便携式订购保证,您有几个选择。最明显的是公平性设置为true的情况:
// 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();
}
// 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();
}
另一个是单一许可和公平设置为true的:
// 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();
}
// 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();
}
这两者的行为非常相似。是的,有更简单的方法可以做到这一点。最简单的方法是只使用显示器,没有等待、睡眠或任何其他恶作剧:
// 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的内置监视器提供了您所需要的语义。唯一的问题是线程持有锁的顺序不能保证;这取决于底层操作系统如何处理锁排序(信号量或互斥量或其他)。操作系统可以很好地保证您需要的行为,但这通常不是可移植的
如果您需要便携式订购保证,您有几个选择。最明显的是公平性设置为true的情况:
// 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();
}
// 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();
}
另一个是单一许可和公平设置为true的:
// 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();
}
// 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();
}
这两者的行为非常相似。任务的顺序重要吗?@NarendraPathai yeah必须维护顺序
执行者呢。newSingleThreadExecutor()
?任务的顺序重要吗?@NarendraPathai yeah必须维护顺序执行者呢。newSingleThreadExecutor()
?请您像我一样发布更新后的代码,这将有助于更好地理解,Thanks@user1881169你应该先自己试一试,如果有什么问题,你可以再问一次我们是来帮助你的。谢谢,但我无法做到这一点,如果你能发布更新的代码,这将是一个很大的帮助,提前感谢这将有所帮助。如果您仍然无法获得您的更新代码,并将提供帮助:)我已经通过了,但无法完全理解,请帮助我,因为我卡住了,我必须通过执行者转换上述方法,我完全卡住了,提前谢谢你能不能像我一样发布更新后的代码,这将有助于更好地理解,Thanks@user1881169你应该先自己试一试,如果有什么问题,你可以再问一次我们是来帮助你的。谢谢,但我无法做到这一点,如果你能发布更新的代码,这将是一个很大的帮助,提前感谢这将有所帮助。如果您仍然无法获得您的更新代码,并将提供帮助:)我已经通过,但无法完全理解,请帮助我,因为我感到困惑,我必须通过执行者转换上述方法,我完全困惑,谢谢advance@TomAnderson..Thanks很多你建议的两种方法真的很有帮助,你能像我一样发布完整的更新代码吗?这将有助于更好地理解上述代码不能保证订购!但问题提到订购是必须的maintained@user1881169:不,我不会发布完整的代码。我已经给了你解决这个问题所需要的信息;作为一名程序员,现在该由你来使用它了。@NarendraPathai:synchronized的方法可能不会保留顺序,但是使用ReentrantLock和信号量
的方法确实会保留顺序,因为它们使用的是公平构建的。我链接的javadocs提供了更多信息。@TomAnderson请通过发布代码来通知brother,因为我不明白,所以我被卡住了upThanks@TomAnderson..Thanks很多你建议的两种方法真的很有帮助,你能像我一样发布完整的更新代码吗?这将有助于更好地理解上述代码不能保证订购!但问题提到订购是必须的maintained@user1881169: