Tag: 并发

以线程安全方式发布非线程安全对象字段

我遇到了Java并发问题。 是的,我看了几乎完全相同标题的问题,但他们似乎都在寻求微妙的不同之处。 是的,我在实践中阅读了Java Concurrency 。 是的,我可以看出为什么它是该主题的事实参考。 是的,我已经阅读了专门针对线程安全类中的发布字段的部分。 是的,我仍然会问一个关于Java的并发问题,不管我知道有人会简单地指出我那本书。 这让我很难过 – 我知道你可以通过确保具有易变性和/或同步访问的正确读/写命令,以线程安全的方式轻松发布可变原语字段,并且64位原语需要具有primefaces访问权限由于其读/写操作缺乏primefaces性。 我知道在需要在类的字段的特定“快照”上执行的代码块上使用锁。 我完全知道像AtomicLong 等好东西的原子包。 但是我仍然对将非线程安全对象作为线程安全类中的字段发布感到困惑。 从我所看到的,只要你在getter中返回对它的引用,你就可以在任何时候对调用者提供前所未有的对象内容访问权限。 此外,如果你给一个setter,你允许他们将对象引用设置为一个对象,他们可以在他们使用setter的对象之外控制它们。 无论如何我无法解决从非线程安全对象组成线程安全类而不使它们全部私有/受保护并在类中为所有非线程安全对象的所有方法创建线程安全包装器方法让该类的用户可能想要使用。 这听起来像是一个样板噩梦。 我的意思是,如果你将一个AtomicReference 返回给getter中的对象,他们可以使用.get()再次获得对它的非同步访问。 我考虑的另一种方法是让所有getter基于旧的获取非线程安全对象的新副本,这意味着修改将是无关紧要的,同样适用于setter。 但是Java有一个无可救药的复杂系统来克隆对象(浅拷贝与深拷贝和特定拷贝等),这有点让我无法做到这一点。 而且,这是非常低效的,它不会比使用像Clojure那样为不变性设计的语言更快。 事实上,考虑到这些语言允许多条不可变数据在幕后共享相同的数据,它可能会慢得多。 那么,如何以可行的方式编写已发布的非线程安全对象的线程安全类? 提前致谢。

在SwingWorker中运行ExecutorService是一个好习惯吗?

考虑以下代码: SwingWorker sworker = new SwingWorker() { @Override protected Void doInBackground() throws Exception { ExecutorService executor = Executors.newFixedThreadPool(5); try { for (int j = 0; j < 5; j++) { Callable worker = new MyCallableImpl(); Future future = executor.submit(worker); array[j] = future.get(); } } catch (InterruptedException e) { // some code here } catch (ExecutionException […]

另外运行两个线程的最佳方式?

更新:请参阅此问题的底部以获得完整答案。 我想运行一个辅助线程,以便我的主线程和我的辅助线程交替执行操作(不,我不想在主线程中执行所有操作,它是用于unit testing)。 我提出了两个不同的解决方案,我不知道哪个是最好的,我对第一个问题有疑问: 使用Exchanger 我使用ExchangeR做了一些事情(虽然我不想只交换一个对象)。 @Test public void launchMyTest() { /** * An anonymous class to set some variables from a different thread */ class ThreadTest extends Thread { //declare some various attributes that will be set //NOT DECLARED VOLATILE … public final Exchanger exchanger = new Exchanger(); @Override public void run() { try […]

Disruptor:日记示例

我对有关日记步骤的最常见(或推荐)的disruptor实现感到好奇。 我最常见的问题是: 它是如何实际实现的(例如)? 使用JPA是明智的吗? 什么数据库是常用的(由已经实施破坏者项目的社区)? 在中间处理程序(EventProcessors)中使用是否明智,因此应该保存每条消息的状态,而不是在业务逻辑进程之前和之后? 顺便说一句(对不起,我知道这与日志记录步骤无关),在eventHandler进程中从RingBuffer中删除消息的正确方法是什么(假设消息已经死/过期,应该通过整个程序)。 我想知道类似死信频道模式的东西。 干杯!

信号量如何以及为什么能够提供比初始化时更多的许可证?

我正在阅读Java Concurrency in Practice一书。 在有关java.util.concurrent.Semaphore的部分java.util.concurrent.Semaphore ,本书中包含以下行。 它是关于其“虚拟许可”对象的实现的评论 该实现没有实际的许可对象,并且Semaphore不会将分配的许可与线程相关联,因此在一个线程中获取的许cocoa以从另一个线程中释放。 您可以将acquire视为消费许可并将其release为创建许可; Semaphore不仅限于创建它的许可数量。 有人可以解释一下吗? 我无法理解这一点。 如果我们创建一个固定大小的池,我们创建固定数量的“许可”。 从上面的陈述看,“许可证”似乎可以继续增长。 为什么这样设计?

Clojure STM(dosync)x Java同步块

Clojure STM(dosync)方法和Java同步Block有什么区别? 我正在阅读“睡觉的理发师”问题下面的代码。 ( http://www.bestinclass.dk/index.clj/2009/09/scala-vs-clojure-round-2-concurrency.html ) (defn the-shop [a] (print “[k] entering shop” a) (dosync (if (< (count @queue) seats) (alter queue conj a) (print "[s] turning away customer" a)))) 为了避免竞争条件,使用dosync ,所以我问自己“Java同步块有什么区别(STM)”? 它会阻止这个关键代码吗? 提前致谢 ! 丹塔斯

Java内存模型:重新排序和并发锁定

java meomry模型要求同步在同一监视器上synchronize块对这些块中修改的变量强制执行之前的实现。 例: // in thread A synchronized( lock ) { x = true; } // in thread B synchronized( lock ) { System.out.println( x ); } 在这种情况下,只要线程A已经通过了synchronized -block,就可以保证线程B将看到x==true 。 现在我正在重写大量代码以使用java.util.concurrent更灵活(并且说更快)的锁,尤其是ReentrantReadWriteLock 。 所以这个例子看起来像这样: 编辑 :示例被打破,因为我错误地转换了代码,如matt b所示 。 修正如下: // in thread A lock.writeLock().lock(); { x = true; } lock.writeLock().unlock(); // in thread B lock.readLock().lock(); { […]

64位OpenJDK 7/8中并发长写的值完整性保证

注意:此问题与volatile,AtomicLong或所描述的用例中的任何感知缺陷无关。 我试图certificate或排除的财产如下: 鉴于以下内容: 最近的64位OpenJDK 7/8(最好7位,但8位也有帮助) 多处理英特尔基础系统 一个非易失性的长原始变量 多个不同步的mutator线程 一个不同步的观察者线程 是否始终保证观察者会遇到由变异器线程写的完整值,或者是撕裂危险的单词? JLS:不确定 此属性对于32位基元和64位对象引用是存在的,但是对于long和double,JLS不保证: 17.7。 双primefaces和非primefaces的非primefaces处理: 出于Java编程语言存储器模型的目的,对非易失性long或double值的单次写入被视为两个单独的写入:每个32位一半写入一次。 这可能导致线程从一次写入看到64位值的前32位,而从另一次写入看到第二次32位的情况。 但是抱着你的马: […]为了效率,这种行为是特定于实现的; Java虚拟机的实现可以自由地以primefaces方式或分两部分执行对long和double值的写入。 鼓励实现Java虚拟机以避免在可能的情况下拆分64位值。 […] 因此,JLS 允许 JVM实现拆分64位写入,并鼓励开发人员相应地进行调整,但也鼓励 JVM实现者坚持使用64位写入。 我们还没有回答最新版本的HotSpot。 HotSpot JIT:谨慎的乐观 由于单词撕裂最有可能发生在紧密循环和其他热点的范围内,我试图分析JIT编译的实际汇编输出。 简而言之:需要进一步测试,但我只能在long上看到primefaces64位操作。 我使用了hdis ,一个OpenJDK的反汇编插件。 在我老化的OpenJDK 7u25版本中构建并安装了该插件后,我开始编写一个简短的程序: public class Counter { static long counter = 0; public static void main(String[] _) { for (long i = (long)1e12; i […]

ConcurrentLinkedDeque与LinkedBlockingDeque

我需要一个线程安全的LIFO结构,并发现我可以使用Deque线程安全实现。 Java 7引入了ConcurrentLinkedDeque ,Java 6引入了LinkedBlockingDeque 。 如果我只使用addFirst()的非阻塞方法,例如addFirst()和removeFirst() ,它与ConcurrentLinkedDeque有什么区别吗? 即如果你忽略阻塞方面,除了LinkedBlockingDeque有界之外, ConcurrentLinkedDeque和LinkedBlockingDeque之间是否还有其他区别?

Java Double Locking – 有人可以更直接地解释为什么直觉不起作用?

我在这里找到了以下代码: http : //en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java 我试图理解为什么在某些情况下这不起作用。 我阅读了“微妙”问题的解释,并且使用volatile将解决问题,但我有点困惑。 // Broken multithreaded version // “Double-Checked Locking” idiom class Foo { private Helper helper = null; public Helper getHelper() { if (helper == null) { synchronized(this) { if (helper == null) { helper = new Helper(); } } } return helper; } // other functions and members… } 基本上,我是否正确地认为这会失败,因为synchronized块中的helper […]