Tag: multithreading

为什么`synchronized(new Object()){}`没有操作?

在下面的代码中: class A { private int number; public void a() { number = 5; } public void b() { while(number == 0) { // … } } } 如果方法b被调用,然后一个新的线程开始引发方法a,那么方法b不能保证看到数字的变化,因此b可能永远不会终止。 当然,我们可以通过number来解决这个问题。 但是出于学术的原因,我们假设volatile不是一个select: JSR-133常见问题告诉我们: 在我们退出一个同步块之后,我们释放监视器, 将caching刷新到主内存 ,这样这个线程所做的写操作对其他线程是可见的。 在我们可以input一个同步块之前,我们需要获取监视器,这会使本地处理器caching失效,从而使variables从主内存中重新加载。 这听起来就像我只需要a和b可以进入和退出任何synchronized -Block,不pipe他们使用什么监视器。 更确切地说,这听起来像这样…: class A { private int number; public void a() { number = 5; synchronized(new Object()) {} […]

等到Future <T>中的任何一个完成

我有很less的asynchronous任务正在运行,我需要等到至less有一个任务完成(将来可能需要等待N个任务完成)。 目前他们被提呈为未来,所以我需要类似的东西 /** * Blocks current thread until one of specified futures is done and returns it. */ public static <T> Future<T> waitForAny(Collection<Future<T>> futures) throws AllFuturesFailedException 有没有这样的事情? 或者任何类似的,对于未来不是必需的。 目前我通过收集期货循环,检查是否完成,然后睡一会儿再检查。 这看起来不是最好的解决scheme,因为如果我长时间睡眠,那么不必要的延迟就会增加,如果我睡了很短的时间就会影响性能。 我可以尝试使用 new CountDownLatch(1) 并在任务完成时减less倒计时 countdown.await() ,但是我发现只有我控制Future的创造才有可能。 这是可能的,但是需要系统重新devise,因为目前创build任务的逻辑(发送Callable到ExecutorService)与决定等待哪个Future是分开的。 我也可以覆盖 <T> RunnableFuture<T> AbstractExecutorService.newTaskFor(Callable<T> callable) 并创buildRunnableFuture的自定义实现,具有附加侦听器以在任务完成时得到通知的能力,然后将这个侦听器附加到需要的任务并使用CountDownLatch,但这意味着我必须重写newTaskFor对于我使用的每个ExecutorService – 并且可能会有实现不扩展AbstractExecutorService。 我也可以尝试包装给定ExecutorService出于同样的目的,但是我必须装饰所有产生期货的方法。 所有这些解决scheme可能工作,但似乎很不自然。 它看起来像我缺less一些简单的东西,比如 WaitHandle.WaitAny(WaitHandle[] waitHandles) 在C#中。 有这样的问题有什么众所周知的解决scheme吗? 更新: 本来我根本没有进入未来的创造,所以没有优雅的解决scheme。 重新devise系统后,我有权访问未来创build,并能够添加countDownLatch.countdown()执行过程,然后我可以countDownLatch.await(),一切工作正常。 […]

Threaded Django任务不会自动处理事务或数据库连接?

我已经设置Django在自己的线程中运行一些重复的任务,我注意到他们总是留下未完成的数据库连接进程(pgsql“空闲事务”)。 我查看了Postgres日志,发现交易没有完成(没有ROLLBACK)。 我尝试在我的函数上使用各种事务装饰器,没有运气。 我切换到手动事务pipe理,手动进行回滚,工作,但仍然离开进程“空闲”。 那么我打电话connection.close(),一切都很好。 但是我仍然想知道,为什么Django的典型事务和连接pipe理对于正在从主Django线程产生的这些线程化任务起作用呢?

如何检测和debuggingmultithreading问题?

这是这个问题的后续,在这一点上我没有得到任何意见。 这里是一个简单的问题: 是否有可能检测和debugging来自multithreading代码的问题? 通常我们必须告诉我们的客户:“我们不能在这里重现问题,所以我们不能修复它,请告诉我们重现问题的步骤,然后我们将解决它。 如果我知道这是一个multithreading问题,但是大多数情况下我不知道这是一个不知何故的答案。 我怎样才能知道一个问题是一个multithreading问题,以及如何debugging? 我想知道是否有任何特殊的日志框架,debugging技术或代码检查器,或其他任何东西来帮助解决这些问题。 一般方法是受欢迎的。 如果有任何答案应该是语言相关的,那么把它保持到.NET和Java。

SyncRoot模式有什么用?

我正在阅读描述SyncRoot模式的ac#书。 表明 void doThis() { lock(this){ … } } void doThat() { lock(this){ … } } 并与SyncRoot模式进行比较: object syncRoot = new object(); void doThis() { lock(syncRoot ){ … } } void doThat() { lock(syncRoot){ … } } 不过,我不太了解这里的区别。 似乎在两种情况下,两种方法一次只能由一个线程访问。 本书描述了…因为实例的对象也可以用于从外部进行同步访问,并且不能控制这个表格的类本身,所以可以使用SyncRoot模式 Eh? “实例的对象”? 谁能告诉我上面两种方法的区别? 提前致谢

什么`std :: kill_dependency`做,为什么我想要使用它?

我一直在阅读有关新的C ++ 11内存模型,我已经遇到了std::kill_dependency函数(§29.3/ 14-15)。 我正在努力理解为什么我会想要使用它。 我在N2664提案中find了一个例子,但没有多大帮助。 它首先显示没有std::kill_dependency代码。 这里,第一行在第二行中携带一个依赖项,它依赖于索引操作,然后将依赖项携带到do_something_with函数中。 r1 = x.load(memory_order_consume); r2 = r1->index; do_something_with(a[r2]); 还有一个例子使用std::kill_dependency来打破第二行和索引之间的依赖关系。 r1 = x.load(memory_order_consume); r2 = r1->index; do_something_with(a[std::kill_dependency(r2)]); 据我所知,这意味着索引和对do_something_with的调用在第二行之前是不依赖的。 根据N2664: 这允许编译器将调用重新sorting为do_something_with ,例如,通过执行预测优化来预测a[r2]的值。 为了调用do_something_with的值a[r2]是需要的。 如果假设编译器“知道”数组填充了零,则可以优化对do_something_with(0);调用do_something_with(0); 并根据其他两个指令重新sorting此通话。 它可以产生以下任何一种: // 1 r1 = x.load(memory_order_consume); r2 = r1->index; do_something_with(0); // 2 r1 = x.load(memory_order_consume); do_something_with(0); r2 = r1->index; // 3 do_something_with(0); r1 = x.load(memory_order_consume); […]

并发JUnittesting

我有一个很大的JUnittesting套件,我很想同时运行所有的testing,原因有两个: 利用多个内核来更快地运行整个testing套件 希望能够检测到由于非线程安全的全局对象造成的一些错误 我认识到这将迫使我重构一些代码,使其线程安全,但我认为这是一件好事:-) 让JUnit同时运行所有testing的最好方法是什么?

如何findManualResetEvent的状态?

我正在使用ManualResetEvent的实例来控制线程对资源的访问,但是我遇到了问题。 有没有人知道我怎么能在debugging过程中发现对象的状态? 这就是说,我想知道,如果ManualResetEvent当前阻止任何线程,甚至可能有多less,哪些线程阻止。

Java同步列表

我有一个预先填充的数组列表。 我有多个线程将从数组列表中删除元素。 每个线程调用下面的remove方法,并从列表中删除一个项目。 下面的代码是否给我一致的行为? ArrayList<String> list = Collections.synchronizedList(new ArrayList<String>()); void remove(String item) { do something; (doesn't work on the list) list.remove(item); } 谢谢!

如何获得整数线程ID在C + + 11

c ++ 11有可能获得当前的线程ID,但它不能转换为整数types: cout<<std::this_thread::get_id()<<endl; 输出:139918771783456 cout<<(uint64_t)std::this_thread::get_id()<<endl; 错误:从types'std :: thread :: id'转换为types'uint64_t'无效从其他types相同:从types'std :: thread :: id'无效转换types'uint32_t' 我真的不想做指针投射得到整数线程ID。 有没有一些合理的方法(标准,因为我希望它是便携式)做到这一点?