我正在学习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