Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
微调Java同步块行为_Java_Multithreading_Synchronization - Fatal编程技术网

微调Java同步块行为

微调Java同步块行为,java,multithreading,synchronization,Java,Multithreading,Synchronization,我有两个同步的代码块。我需要两个代码块不能在两个或多个不同的线程中同时运行,但我希望允许两个或多个不同的线程同时运行其中一个代码块。如何在Java中实现这一点?举例说明: class HelloWorld { method1() { synchronized (?) { //block 'A' //I want to allow 2+ threads to run this code block simultaneously }

我有两个同步的代码块。我需要两个代码块不能在两个或多个不同的线程中同时运行,但我希望允许两个或多个不同的线程同时运行其中一个代码块。如何在Java中实现这一点?举例说明:

class HelloWorld {

    method1() {
        synchronized (?) { //block 'A'
            //I want to allow 2+ threads to run this code block simultaneously
        }
    }

    method2() {
        synchronized (?) { //block 'B'
            //this should block while another thread is running
            //the synchronized block 'A'
        }
    }

我不希望两个同步块都锁定在同一个对象/类上,因为这将禁止第一个块由多个线程同时运行。但是,这是我所知道的防止块A和块B由2个或更多线程同时运行的唯一方法。必须有一种方法来实现这一点。

我建议研究实现类的各个方面。这个东西特别设计成允许多个“阅读器”线程;但只有一条“作者”线索

如果我没看错你的问题,那正是你想要的。另一方面,退后一步,明确你要解决的真正问题可能也是明智的

特别是考虑到上述锁与Java8配合良好,但在早期版本的Java中出现了问题。

可能类似于:

private CommonStateSynchronizer synchronizer = new CommonStateSynchronizer();

public void method1() throws InterruptedException
{
    synchronizer.run("method1", () -> {
        // do method1
    });
}

public void method2() throws InterruptedException
{
    synchronizer.run("method2", () -> {
        // do method2
    });
}

public static class CommonStateSynchronizer
{
    private final ReentrantReadWriteLock rw;
    private final ReentrantReadWriteLock.ReadLock r; // hold read lock while executing in current state
    private final ReentrantReadWriteLock.WriteLock w; // hold write lock while checking or changing state
    private final Condition stateChanged;
    private volatile String currentState; // do not modify unless holding write lock

    public CommonStateSynchronizer()
    {
        rw = new ReentrantReadWriteLock(true);
        r = rw.readLock();
        w = rw.writeLock();
        stateChanged = w.newCondition();
    }

    public void run(String state, Runnable runnable) throws InterruptedException {
        w.lock();

        while (!state.equals(currentState))
        {
            if (currentState == null)
            {
                currentState = state;
                stateChanged.notifyAll();
                break;
            }
            stateChanged.await();
        }
        assert state.equals(currentState);

        // downgrade to concurrent read lock
        r.lock();
        w.unlock();

        try
        {
            runnable.run();
        }
        finally
        {
            r.unlock();
            w.lock();

            if (rw.getReadLockCount() == 0)
            {
                currentState = null;
                stateChanged.notifyAll();
            }
            w.unlock();
        }
    }
}

我会重新思考您为什么需要这个,因为很可能有一种方法可以实现您的解决方案,所以这不是一个要求。为什么类名为
HelloWorld
?这是你第一次尝试Java吗?如果是这样,就远离并发性。Kayaman,类名有什么区别?这是你第一次尝试提供有用的评论吗?