当前位置: 首页 > 面试题库 >

互斥方法

宁欣怿
2023-03-14
问题内容

我正在学习Java多线程编程。我有以下逻辑:

假设我有A班

class A {
    ConcurrentMap<K, V> map;

    public void someMethod1 () {
        // operation 1 on map
        // operation 2 on map
    }

    public void someMethod2 () {
        // operation 3 on map
        // operation 4 on map
    }
}

现在,我不需要同步“ someMethod1”或“ someMethod2”中的操作。这意味着,如果有两个线程同时调用“
someMethod1”,则无需序列化这些操作(因为ConcurrentMap将完成此工作)。

但是我希望“ someMethod1”和“ someMethod2”彼此互斥,这意味着当某个线程正在执行“
someMethod1”时,另一个线程应等待输入“ someMethod2”(但应允许另一个线程输入“ someMethod1”)。

简而言之,有没有一种方法可以使“ someMethod1”和“ someMethod2”不是互斥体,而是互斥体?

我希望我的问题已经足够清楚了…

谢谢!


问题答案:

我尝试了几次使用更高级别的构造的尝试,但没有想到。我认为这可能是一个下降到低级API的机会:

编辑:
我实际上认为您正在尝试设置一个固有的棘手问题(请参阅第二至第二段),并且可能不需要(请参阅最后一段)。但这就是说,这是可以完成的方法,我将在此答案的结尾处留下颜色评论。

private int someMethod1Invocations = 0;
private int someMethod2Invocations = 0;

public void someMethod1() {
    synchronized(this) {
        // Wait for there to be no someMethod2 invocations -- but
        // don't wait on any someMethod1 invocations.
        // Once all someMethod2s are done, increment someMethod1Invocations
        // to signify that we're running, and proceed
        while (someMethod2Invocations > 0)
            wait();
        someMethod1Invocations++;
    }

    // your code here

    synchronized (this) {
        // We're done with this method, so decrement someMethod1Invocations
        // and wake up any threads that were waiting for that to hit 0.
        someMethod1Invocations--;
        notifyAll();
    }
}

html" target="_blank">public void someMethod2() {
    // comments are all ditto the above
    synchronized(this) {
        while (someMethod1Invocations > 0)
            wait();
        someMethod2Invocations++;
    }

    // your code here
    synchronized(this) {
        someMethod2Invocations--;
        notifyAll();
    }
}

上面的一个明显问题是它可能导致线程饥饿。例如,someMethod1()正在运行(并阻塞someMethod2()),并且在即将完成时,另一个线程随之出现并调用someMethod1()。这样就可以进行了,就在结束时
另一个
线程开始了someMethod1(),依此类推。在这种情况下,someMethod2()将永远没有机会运行。实际上,这并不是上面代码中的直接错误。这是您非常需要设计的问题,一个好的解决方案应该积极地解决这个问题。我认为一个公平的AbstractQueuedSynchronizer可以解决问题,尽管这是留给读者的练习。:)

最后,我ConcurrentHashMap忍不住要发表意见:鉴于操作相当快,因此最好在这两种方法之间放一个互斥体,然后用它完成。因此,是的,线程将不得不排队等待调用someMethod1(),但是每个线程将非常快速地完成其轮换(并让其他线程继续进行)。这不应该是一个问题。



 类似资料:
  • 问题内容: 阅读有关锁定PHP的一些文章。 它们主要都直接指向http://php.net/manual/en/function.flock.php。 本页讨论如何在硬盘上打开文件! 真的是这样吗?我的意思是,这使锁定变得非常昂贵-这意味着每次要锁定时,我都必须访问硬盘)= 能再给我一个令人愉快的消息安慰我吗? 编辑: 由于我已经收到了一些答复,我想问这个。 我的脚本只能由一个或多个线程运行?因为

  • 互斥是多线程系统中用于控制访问的一个原对象(primitive object)。下面的例子给出了它最基本的用法: std::mutex m; int sh; //共享数据 // … m.lock(); // 对共享数据进行操作: sh += 1; m.unlock(); 在任何时刻,最多只能有一个线程执行到lock()和unlock()之间的区域(通常称为临界区)。当第一个线程正在临界区执行时

  • Go语言包中的 sync 包提供了两种锁类型:sync.Mutex 和 sync.RWMutex。 Mutex 是最简单的一种锁类型,同时也比较暴力,当一个 goroutine 获得了 Mutex 后,其他 goroutine 就只能乖乖等到这个 goroutine 释放该 Mutex。 RWMutex 相对友好些,是经典的单写多读模型。在读锁占用的情况下,会阻止写,但不阻止读,也就是多个 gor

  • 上面的例子中,我们看过了如何在多个协程之间原子地访问计数器,对于更复杂的例子,我们可以使用Mutex来在多个协程之间安全地访问数据。 package main import ( "fmt" "math/rand" "runtime" "sync" "sync/atomic" "time" ) func main() { // 这个例子的状态就

  • 线程使用互斥量保护共享资源 线程使用互斥量保护共享资源 源码/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-08-24 yangjie the first versi

  • 互斥量接口 结构体 struct   rt_mutex   互斥量控制块 更多...   类型定义 typedef struct rt_mutex *  rt_mutex_t   互斥量类型指针定义   函数 rt_err_t  rt_mutex_init (rt_mutex_t mutex, const char *name, rt_uint8_t flag)   初始化互斥量   rt_err