关于不同的同步方法

时间:2012-12-09 08:58:13

标签: java multithreading executors

请不要将以下问题视为重复问题..!

我开发了一个类,让多个线程按顺序运行,一次一个,按顺序运行。此类的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();
            }
        }
    }
}

2 个答案:

答案 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();
}

这两个行为非常相似。