我必须通过并行交换随机索引元素来对数组进行洗牌。我的问题是如何防止其他线程读取和写入当前正在被另一个线程交换的元素。我不想在一个线程交换时锁定整个数组。
我想让几个线程同时交换不同的元素对。
我尝试过这样的事情:
object[] lockArray = new object[array.Length];
for (int i = 0; i < array.Length; i++)
lockArray[i] = new object();
for (int i = 0; i < thredCount; i++)
{
Thread t = new Thread(th => Shuffle.Shuflle(array,lockArray));
t.Start();
}
public class Shuffle
{
public static void Shuflle(char[] array,object [] lockArray)
{
for (int count = array.Length - 1; count > 1; count--)
{
Random rand = new Random();
int y = rand.Next(count) + 1;
lock (lockArray[count])
{
lock (lockArray[y]) …
Run Code Online (Sandbox Code Playgroud) 我正在使用PCLStorage库访问多个平台上的文件。该库仅提供异步方法。我在lock
块内使用这些方法,以便它们可以同步运行。我习惯.Result
等待通话结果。我试图捕获此锁内的异常,但由于AggregateException
抛出了异常,因此它不会到达我的 catch 块。
lock (this)
{
try
{
IFile file = folder.GetFileAsync (FileName).Result;
}
catch (FileNotFoundException)
{
//won't be catched
}
}
Run Code Online (Sandbox Code Playgroud)
如何捕获内部抛出的原始异常lock
?
我不确定什么时候打电话RedisLockRegistry.obtain(String lockKey)
(或者,更一般地说,LockRegistry.obtain(String lockKey)
)。我应该在应用程序开始时只获得一次锁,然后像往常一样锁定/解锁它,还是应该在每次调用 lock 之前(在我使用它之前)获得一个锁?
目前我正在使用后一个选项,但是,我不确定这是否真的有必要。
类成员函数将在其or上使用mutex
and 。我可以看到这可以通过两种不同的方式来完成。lock_guard
critical section
critical data
情况 1: - for 循环内部。lock_guard
在每次迭代中构造和销毁。
std::mutex s_mutex;
class Foo {
public:
void bar() {
for ( ... ) {
std::lock_guard<std::mutex> guard( s_mutex );
// critical section data
} // lock_guard goes out of scope and releases or unlocks mutex
}
};
Run Code Online (Sandbox Code Playgroud)
情况 2: -在 for 循环之外。lock_guard
创建一次,然后在循环完成后销毁。
std::mutex s_mutex;
class Foo {
public:
void bar() {
std::lock_guard<std::mutex> guard( s_mutex );
for ( ... ) {
// data …
Run Code Online (Sandbox Code Playgroud) 我正在阅读一些源代码并locking
在 Clojure 中遇到了用法。这让我想到了 atom 版本。那么2个代码片段之间有什么区别,我认为它们做同样的事情?
(def lock (Object.))
(locking lock
...some operation)
Run Code Online (Sandbox Code Playgroud)
(def state (atom true))
(when @state
(reset! state false)
...some operation
(reset! state true))
Run Code Online (Sandbox Code Playgroud) 在旧的同步块中,我们使用相同的对象进行同步,还使用了等待和通知方法。所以他们都可以引用同一个锁。说得通。
那么当我使用类 ReentrantLock 时,为什么我不能也使用相同的变量来调用lock、unlock以及await和signal?为什么我需要创建额外的 Condition 变量?
也就是说,为什么我需要这样做:
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
void doSomething() {
lock.lock();
//some code
condition.await();
//some code
lock.unlock();
}
Run Code Online (Sandbox Code Playgroud)
而不是这样:(这种类型的编码不会更合乎逻辑)?
Lock lock = new ReentrantLock();
void doSomething() {
lock.lock();
//some code
lock.await();
//some code
lock.unlock();
}
Run Code Online (Sandbox Code Playgroud)
编辑:来自文档:一个 Condition 实例本质上绑定到一个锁。 为什么要这样设计?为什么不只有一个 Lock 类型的变量,它会有 await 和信号方法?
在我的代码库中,我有两个看起来像这样的函数:
void inside() {
lock_guard<mutex> lock(LOCK);
cout << "Finished inside" << endl;
}
void outside() {
lock_guard<mutex> lock(LOCK);
inside();
cout << "Finished outside" << endl;
}
Run Code Online (Sandbox Code Playgroud)
这会导致我的代码库中出现死锁,我觉得这很奇怪,因为我的印象是 lock_guard 在超出范围时会被破坏。我也尝试过使用 unique_lock,但得到了相同的结果。我能够解决它的唯一方法是在调用内部之前调用 unlock:
void outside() {
LOCK.lock();
// Do stuff
LOCK.unlock();
inside();
cout << "Finished outside" << endl;
}
Run Code Online (Sandbox Code Playgroud) 我在查看可重入锁的 Java 文档时发现了以下文本:
锁的公平性并不能保证线程调度的公平性。因此,使用公平锁的许多线程之一可能会连续多次获得公平锁,而其他活动线程没有进展并且当前没有持有该锁。
根据我的理解,这意味着,如果操作系统调度程序调度相同的线程(之前获取锁)并且它尝试再次获取相同的锁,Java将允许它获取并且不会遵守公平参数值。有人可以告诉我公平参数的目的是什么以及在什么情况下应该使用它。
我只是在想它是否就像一个优先级值,这可能会影响调度程序但不能保证线程执行顺序。
我想更改 Postgres 数据库中几个表的架构。问题是,始终存在长时间运行的查询,并且据我了解,模式更改需要独占锁。
问题是我该怎么做?当然,我可以终止所有现有查询并尝试进行架构重命名(将表移动到不同的架构),但同时很有可能会出现新查询。
感谢帮助!
我正在学习 Java 中的多线程,我有一个简短的问题。我有一个同步块或方法和 2 个(或更多)线程。而且我只有一个只有一个核心的CPU,因此当CPU决定从一个线程切换到另一个线程时,2个线程将按顺序工作。
public synchronized void doSomething() {
// do something
}
Run Code Online (Sandbox Code Playgroud)
因此,一次只有一个线程会执行此方法,因为它是同步的。另一个线程被阻塞,在第一个线程完成执行之前无法执行该方法。
我认为有两种情况,CPU可以在thread1完成doSomething()的执行之前将执行从thread1切换到thread2。如果CPU这样做,则意味着线程1将停止执行doSomething()并让它未完成,线程2将看到doSomething()被锁定,因为线程1执行了它。之后我认为CPU会切换回thread1并继续执行doSomething()。在 CPU 切换回线程 2 之前,线程 1 可能会再次开始执行 doSomething() 。
第二种情况,线程1执行doSomething(),线程2在线程1执行该方法的整个期间被阻塞。当线程 1 完成 doSomething() 的执行后,CPU 将切换到线程 2,该线程将开始执行 doSOthing(),因为此时该方法尚未锁定。
有人可以向我解释什么是正确的情况吗?
locking ×10
java ×4
c# ×2
mutex ×2
arrays ×1
async-await ×1
atomic ×1
c++ ×1
c++17 ×1
clojure ×1
concurrency ×1
cpu ×1
locks ×1
postgresql ×1
spring ×1
synchronized ×1