<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.comp.java.jsr.166-concurrency">
    <title>gmane.comp.java.jsr.166-concurrency</title>
    <link>http://blog.gmane.org/gmane.comp.java.jsr.166-concurrency</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9515"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9506"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9501"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9496"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9486"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9467"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9444"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9415"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9414"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9392"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9375"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9363"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9334"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9328"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9287"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9284"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9272"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9260"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9242"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9232"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9515">
    <title>Some fork/join threads idle when workload isnon-uniform</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9515</link>
    <description>&lt;pre&gt;We have a multithreaded application which relies heavily on the F/J 
framework. When threadprofiling the application we've observed that not 
all F/J threads are kept busy. Some threads spend a lot of time waiting, 
thus making suboptimal use of the available CPUs in the system.

I've discovered it may have something to do with the workload 
distribution. The tasks are being spawned according to a quad-tree 
structure. When each branch in the quad tree has roughly the same amount 
of work to do, all F/J threads are nicely occupied (uniform workload). 
When some branches however have a lot more work to do, while others 
don't, some F/J threads are waiting (non-uniform workload).

I am guessing it has something to do with a suboptimality in work 
stealing: in the case of uniform workload, there is little to no work 
stealing going on, and everything behaves nicely. In the case of 
non-uniform workload, there is (a lot?) more work stealing going on, 
which somehow results in waiting F/J threads.

I have attached the following files to illustrate my case:

  * ForkJoinWithUniformWorkload.java: illustrates the 'well-behaved'
    case where all F/J threads are busy (optimal usage of multi-core CPU)
  * ForkJoinWithNonUniformWorkload.java: illustrates the 'ill-behaved'
    case where one F/J thread is waiting all the time (suboptimal usage
    of multi-core CPU)
  * ForkJoinWithUniformWorkload.png: JVisualVM snapshot (screenshot) of
    the ForkJoinWithUniformWorkload program, where you can see all 4
    threads occupied
  * ForkJoinWithNonUniformWorkload.png: JVisualVM snapshot (screenshot)
    of the ForkJoinWithNonUniformWorkload program, where you can see 1
    thread sleeping. This is similar to what we see in our real-life
    application, although in our real-life application we've observed 3
    out of 8 threads waiting while only 5 are doing actual work. Note
    that this behavior is not 100% reproducible, but often enough to be
    investigated thoroughly
  * threaddump-*.tdump: thread dump of the case where the thread
    "ForkJoinPool-1-worker-1"
    of the 4 F/J threads is waiting (tryAwaitDone).

I would like to:

 1. Understand why the application is behaving this way
 2. Find a solution so that our application makes optimal use of all
    available CPUs in all circumstances


Best regards,

Peter De Maeyer

2011-12-08 07:50:56
Full thread dump Java HotSpot(TM) Server VM (21.1-b02 mixed mode):

"RMI TCP Connection(2)-127.0.0.1" daemon prio=10 tid=0x08d93400 nid=0x4ea6 runnable [0x6ed5c000]
   java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
- locked &amp;lt;0xa1965628&amp;gt; (a java.io.BufferedInputStream)
at java.io.FilterInputStream.read(FilterInputStream.java:83)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

   Locked ownable synchronizers:
- &amp;lt;0xa157d068&amp;gt; (a java.util.concurrent.ThreadPoolExecutor$Worker)

"JMX server connection timeout 17" daemon prio=10 tid=0x08d60000 nid=0x4ea4 in Object.wait() [0x6edad000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on &amp;lt;0xa16fa210&amp;gt; (a [I)
at com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:168)
- locked &amp;lt;0xa16fa210&amp;gt; (a [I)
at java.lang.Thread.run(Thread.java:722)

   Locked ownable synchronizers:
- None

"RMI Scheduler(0)" daemon prio=10 tid=0x08d5ac00 nid=0x4ea2 waiting on condition [0x6edfe000]
   java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  &amp;lt;0xa151e960&amp;gt; (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1090)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1043)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1103)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

   Locked ownable synchronizers:
- None

"RMI TCP Connection(1)-127.0.0.1" daemon prio=10 tid=0x08a70800 nid=0x4ea1 runnable [0x6f156000]
   java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
- locked &amp;lt;0xa169ce90&amp;gt; (a java.io.BufferedInputStream)
at java.io.FilterInputStream.read(FilterInputStream.java:83)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

   Locked ownable synchronizers:
- &amp;lt;0xa157cc28&amp;gt; (a java.util.concurrent.ThreadPoolExecutor$Worker)

"RMI TCP Accept-0" daemon prio=10 tid=0x08cdc000 nid=0x4e9e runnable [0x6f1a7000]
   java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:396)
at java.net.ServerSocket.implAccept(ServerSocket.java:522)
at java.net.ServerSocket.accept(ServerSocket.java:490)
at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:52)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:387)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:359)
at java.lang.Thread.run(Thread.java:722)

   Locked ownable synchronizers:
- None

"Attach Listener" daemon prio=10 tid=0x092c3800 nid=0x4e9c waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
- None

"ForkJoinPool-1-worker-4" daemon prio=10 tid=0x08a7b400 nid=0x4e11 runnable [0x6f6b9000]
   java.lang.Thread.State: RUNNABLE
at java.lang.StrictMath.atan(Native Method)
at java.lang.Math.atan(Math.java:204)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.doSomething(ForkJoinWithNonUniformWorkLoad.java:67)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:59)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:52)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:52)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:53)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:51)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:51)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:51)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:334)
at java.util.concurrent.ForkJoinWorkerThread.helpJoinTask(ForkJoinWorkerThread.java:812)
at java.util.concurrent.ForkJoinWorkerThread.joinTask(ForkJoinWorkerThread.java:727)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:362)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:53)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:334)
at java.util.concurrent.ForkJoinWorkerThread.execTask(ForkJoinWorkerThread.java:604)
at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:762)
at java.util.concurrent.ForkJoinPool.work(ForkJoinPool.java:646)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:398)

   Locked ownable synchronizers:
- None

"ForkJoinPool-1-worker-3" daemon prio=10 tid=0x08a79c00 nid=0x4e10 runnable [0x6f70a000]
   java.lang.Thread.State: RUNNABLE
at java.lang.StrictMath.atan(Native Method)
at java.lang.Math.atan(Math.java:204)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.doSomething(ForkJoinWithNonUniformWorkLoad.java:67)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:59)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:52)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:52)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:53)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:51)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:51)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:51)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:334)
at java.util.concurrent.ForkJoinWorkerThread.execTask(ForkJoinWorkerThread.java:604)
at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:762)
at java.util.concurrent.ForkJoinPool.work(ForkJoinPool.java:646)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:398)

   Locked ownable synchronizers:
- None

"ForkJoinPool-1-worker-2" daemon prio=10 tid=0x08a78000 nid=0x4e0f runnable [0x6f75b000]
   java.lang.Thread.State: RUNNABLE
at java.lang.StrictMath.atan(Native Method)
at java.lang.Math.atan(Math.java:204)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.doSomething(ForkJoinWithNonUniformWorkLoad.java:67)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:59)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:51)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:53)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:52)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:53)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:51)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:51)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:51)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:355)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:51)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:334)
at java.util.concurrent.ForkJoinWorkerThread.execTask(ForkJoinWorkerThread.java:604)
at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:762)
at java.util.concurrent.ForkJoinPool.work(ForkJoinPool.java:646)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:398)

   Locked ownable synchronizers:
- None

"ForkJoinPool-1-worker-1" daemon prio=10 tid=0x6ff40800 nid=0x4e0e in Object.wait() [0x6f7ac000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on &amp;lt;0x747d4188&amp;gt; (a ForkJoinWithNonUniformWorkLoad$NonUniformWorkload)
at java.util.concurrent.ForkJoinTask.tryAwaitDone(ForkJoinTask.java:264)
- locked &amp;lt;0x747d4188&amp;gt; (a ForkJoinWithNonUniformWorkLoad$NonUniformWorkload)
at java.util.concurrent.ForkJoinPool.tryAwaitJoin(ForkJoinPool.java:1043)
at java.util.concurrent.ForkJoinWorkerThread.joinTask(ForkJoinWorkerThread.java:731)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:362)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at ForkJoinWithNonUniformWorkLoad$NonUniformWorkload.compute(ForkJoinWithNonUniformWorkLoad.java:52)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:93)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:334)
at java.util.concurrent.ForkJoinWorkerThread.execTask(ForkJoinWorkerThread.java:604)
at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:784)
at java.util.concurrent.ForkJoinPool.work(ForkJoinPool.java:646)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:398)

   Locked ownable synchronizers:
- None

"Service Thread" daemon prio=10 tid=0x6ff04800 nid=0x4e0c runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
- None

"C2 CompilerThread1" daemon prio=10 tid=0x6ff02800 nid=0x4e0b waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
- None

"C2 CompilerThread0" daemon prio=10 tid=0x6ff00800 nid=0x4e0a waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
- None

"Signal Dispatcher" daemon prio=10 tid=0x089bbc00 nid=0x4e09 runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
- None

"Finalizer" daemon prio=10 tid=0x08982c00 nid=0x4e07 in Object.wait() [0x6fc22000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on &amp;lt;0x747d2c50&amp;gt; (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
- locked &amp;lt;0x747d2c50&amp;gt; (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)

   Locked ownable synchronizers:
- None

"Reference Handler" daemon prio=10 tid=0x0897dc00 nid=0x4e06 in Object.wait() [0x6fc73000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on &amp;lt;0x747d0500&amp;gt; (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
- locked &amp;lt;0x747d0500&amp;gt; (a java.lang.ref.Reference$Lock)

   Locked ownable synchronizers:
- None

"main" prio=10 tid=0x0886a000 nid=0x4dfc in Object.wait() [0xb697b000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on &amp;lt;0x747d4160&amp;gt; (a ForkJoinWithNonUniformWorkLoad$NonUniformWorkload)
at java.lang.Object.wait(Object.java:503)
at java.util.concurrent.ForkJoinTask.externalAwaitDone(ForkJoinTask.java:287)
- locked &amp;lt;0x747d4160&amp;gt; (a ForkJoinWithNonUniformWorkLoad$NonUniformWorkload)
at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:365)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:639)
at java.util.concurrent.ForkJoinPool.invoke(ForkJoinPool.java:1521)
at ForkJoinWithNonUniformWorkLoad.main(ForkJoinWithNonUniformWorkLoad.java:16)

   Locked ownable synchronizers:
- None

"VM Thread" prio=10 tid=0x08978000 nid=0x4e05 runnable 

"GC task thread#0 (ParallelGC)" prio=10 tid=0x08871400 nid=0x4dfd runnable 

"GC task thread#1 (ParallelGC)" prio=10 tid=0x08872c00 nid=0x4dfe runnable 

"GC task thread#2 (ParallelGC)" prio=10 tid=0x08874000 nid=0x4dff runnable 

"GC task thread#3 (ParallelGC)" prio=10 tid=0x08875800 nid=0x4e00 runnable 

"GC task thread#4 (ParallelGC)" prio=10 tid=0x08877000 nid=0x4e01 runnable 

"GC task thread#5 (ParallelGC)" prio=10 tid=0x08878400 nid=0x4e02 runnable 

"GC task thread#6 (ParallelGC)" prio=10 tid=0x08879c00 nid=0x4e03 runnable 

"GC task thread#7 (ParallelGC)" prio=10 tid=0x0887b400 nid=0x4e04 runnable 

"VM Periodic Task Thread" prio=10 tid=0x6ff0ec00 nid=0x4e0d waiting on condition 

JNI global references: 198

_______________________________________________
Concurrency-interest mailing list
Concurrency-interest&amp;lt; at &amp;gt;cs.oswego.edu
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
&lt;/pre&gt;</description>
    <dc:creator>Peter De Maeyer</dc:creator>
    <dc:date>2012-05-26T08:55:54</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9506">
    <title>synchronization based on a key</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9506</link>
    <description>&lt;pre&gt;I have a method that needs to be synchronized based on a key passed as
parameter, that is, for same key multiple threads shouldn't be
running. Following is what I did--


static final ConcurrentMap&amp;lt;String,Boolean&amp;gt; IN_PROGRESS =
   new ConcurrentHashMap&amp;lt;String,Boolean&amp;gt;();

void foo(String key){
    if(null == IN_PROGRESS.putIfAbsent(key, Boolean.TRUE)){
      // no other thread is processing this key
      try{
          // process this key
      } finally {
         // done with processing this key
         IN_PROGRESS.remove(key)
      }
    } else {
      // some other thread is running this key, discard it
    }
}

this works if I need to discard the request to process the key from
thread t1 when another thread, t2, is processing that key.

I need help to do following-
make thread t1 wait while t2 is processing the key and resume t1 when
t2 is finish processing same key.

I'm aware that if there are multiple threads t1,t3,t4.. etc waiting
for t2 to finish anyone of these thread can wake up and start
processing the key irrespective of their order (if there is any) of
asking to process the key.

Thanks for help.

Bheem
&lt;/pre&gt;</description>
    <dc:creator>bhm</dc:creator>
    <dc:date>2012-05-24T14:22:37</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9501">
    <title>ForkJoinPool does not achieve expectedparallelism</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9501</link>
    <description>&lt;pre&gt;Hi Doug and all,

Using the latest version of the ForkJoinPool available on the jsr166y
website, we ran into an issue/regression with our existing code base.

In our code, we have a single task that scans a fairly large fact table
while applying some filtering conditions. Any row that passes this
condition must then be processed.
The pattern that we use is that the scanning task saves (in an array) the
rows that passed the condition and forks a processing task as soon as we
have enough rows to process (say 1024).
We expect that these processing tasks will be picked up (i.e. stolen) by
the other threads in the pool and executed while we continue scanning and
filtering.
Unrelated to the current issue, we have a completion phase at the end of
the scanning that ensures all the forked tasks have been executed.

To sum it up, we have a single task that scans some data and forks lots of
processing task.
Previously (with the version from a few months back without the worker
queues), this was working perfectly and all the worker threads were kept
busy and executed the processing tasks.
Now, we see that only a few threads are being kept busy with the processing
tasks (in addition to the scanning task). Dozens of threads are idle while
work is piling up.

If have put together a simple test that exhibits this issue:
http://pastebin.com/qz9uifJW

Looking at the ForkJoinPool code, it looks like the issue could be in
ForkJoinPool.WorkQueue.push().
More specifically, we have the following:
                if ((n = (top = s + 1) - base) &amp;lt;= 2) {
                    if ((p = pool) != null)
                        p.signalWork();
                }

If tasks are being forked quickly enough, we will only signal work twice
while the local queue is getting fairly large, and no extra help is being
made available.
I naively modified this code to the following and got back to the initial
behavior (full threads usage):
                if ((n = (top = s + 1) - base) &amp;lt;= pool.parallelism) {
                    if ((p = pool) != null)
                        p.signalWork();
                }

I'm not quite sure why the initial "2" was put there. Was it to avoid
flooding the threads with signals if everybody is already at work? In that
case we could do the signaling only if the AC count is &amp;lt; 0.
I'm sure there is a more elegant solution available, so any advice on
whether this is indeed a core issue or if there is an issue with our pool
usage would be appreciated!

Thanks,

&lt;/pre&gt;</description>
    <dc:creator>Romain Colle</dc:creator>
    <dc:date>2012-05-22T16:20:47</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9496">
    <title>What's mean TLR?</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9496</link>
    <description>&lt;pre&gt;Hi, all

Here is some lines of comments in ThreadLocalRandom.java

    // Padding to help avoid memory contention among seed updates in
    // different TLRs in the common case that they are located near
    // each other.

What's the above TLR short for ?

Thanks,
Min
&lt;/pre&gt;</description>
    <dc:creator>Min Zhou</dc:creator>
    <dc:date>2012-05-21T07:43:42</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9486">
    <title>Promise implementation?</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9486</link>
    <description>&lt;pre&gt;Hi,

What are the odds of getting a Promise implementation in j.u.c.? I
occasionally find myself needing something like that.

I'm thinking it could perhaps look a bit like this (to show a concrete
example of an API):
https://github.com/chrisvest/concurrency-extras/blob/master/src/main/java/javax/util/concurrent/Promise.java

Cheers,
Chris
_______________________________________________
Concurrency-interest mailing list
Concurrency-interest&amp;lt; at &amp;gt;cs.oswego.edu
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
&lt;/pre&gt;</description>
    <dc:creator>Chris Vest</dc:creator>
    <dc:date>2012-05-19T12:45:48</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9467">
    <title>a volatile bug?</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9467</link>
    <description>&lt;pre&gt;as reported on
http://stackoverflow.com/questions/10620680

basically there are

    volatile int a;
    int b;

Thread 1:

    b=1;
    a=1;

Thread 2:

    while(a==0)
        ;
    if(b==0)
        print("error");

"error" is seen printed on 32 bit JDK6 on 64bit machine
&lt;/pre&gt;</description>
    <dc:creator>Zhong Yu</dc:creator>
    <dc:date>2012-05-16T16:55:00</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9444">
    <title>Garbage collection for parallel data struc</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9444</link>
    <description>&lt;pre&gt;People may find this upcoming paper interesting by a notable researcher and
from a multicore research group:

Can Parallel Data Structures Rely on Automatic Memory
Managers?

Erez Petrank
Dept. of Computer Science
Technion, Israel
erez&amp;lt; at &amp;gt;cs.technion.ac.il

http://safari.ece.cmu.edu/MSPC2012/erez_abstract.pdf
MSPC’12, June 16, 2012, Beijing, China.

ABSTRACT
The complexity of parallel data structures is often measured
by two major factors: the throughput they provide and the
progress they guarantee. Progress guarantees are particu-
larly important for systems that require responsiveness such
as real-time systems, operating systems, interactive systems,
etc. Notions of progress guarantees such as lock-freedom,
wait-freedom, and obstruction-freedom that provide di er-
ent levels of guarantees have been proposed in the literature
[4, 6]. Concurrent access (and furthermore, optimistic ac-
cess) to shared objects makes the management of memory
one of the more complex aspects of concurrent algorithms
design. The use of automatic memory management greatly
simpli es such algorithms [11, 3, 2, 9]. However, while the
existence of lock-free garbage collection has been demon-
strated [5], the existence of a practical automatic memory
manager that supports lock-free or wait-free algorithms is
still open. Furthermore, known schemes for manual recla-
mation of unused objects are di cult to use and impose a
signi cant overhead on the execution [10].


It turns out that the memory management community
is not fully aware of how dire the need is for memory man-
agers that support progress guarantees for the design of concurrent data
structures.

Likewise, designers of concurrent
data structures are not always aware of the fact that mem-
ory management with support for progress guarantees is not
available.

Closing this gap between these two communities
is a major open problem for both communities.
In this talk we will examine the memory management
needs of concurrent algorithms.

Next, we will discuss how state-of-the-art research and practice deal with
the fact that
an important piece of technology is missing (e.g., [7, 1]). Fi-
nally, we will survey the currently available pieces in this
puzzle (e.g., [13, 12, 8]) and specify which pieces are miss-
ing.

This open problem is arguably the greatest challenge
facing the memory management community today.


Copyright 2012 ACM 978-1-4503-1219-6/12/06 ...$10.00.
Categories and Subject Descriptors
D.3.3 [Language Constructs and Features]: Dynamic
storage management, Concurrent programming structures;
D.3.4 [Processors]: Memory management (Garbage Collec-
tion); D.4.2 [Storage Management]: Garbage Collection
General Terms
Algorithms, Design, Performance, Reliability.


1. REFERENCES
[1] D. F. Bacon, P. Cheng, and V. Rajan. A real-time
garbage collector with low overhead and consistent
utilization. In POPL, 2003.
[2] F. Ellen, P. Fatourou, E. Ruppert, and F. van Breugel.
Non-blocking binary search trees. In PODC , 2010.
[3] T. L. Harris. A pragmatic implementation of
non-blocking linked-lists. In DISC, 2001.
[4] M. Herlihy. Wait-free synchronization. ACM Trans.
Program. Lang. Syst., 13(1):124{149, 1991.
[5] M. Herlihy and J. E. B. Moss. Lock-free garbage
collection for multiprocessors. IEEE Trans. Parallel
Distrib. Syst., 3(3):304{311, 1992.
[6] M. Herlihy and N. Shavit. The Art of Multiprocessor
Programming. Morgan Kaufmann, 2008.
[7] R. L. Hudson and J. E. B. Moss. Sapphire: Copying
garbage collection without stopping the world.
Concurrency and Computation: Practice and
Experience, 15(3{5):223{261, 2003.
[8] G. Kliot, E. Petrank, and B. Steensgaard. A lock-free,
concurrent, and incremental stack scanning
mechanism for garbage collectors. Operating Systems
Review, 43(3):3{13, 2009.
[9] A. Kogan and E. Petrank. Wait-free queues with
multiple enqueuers and dequeuers. In PPOPP, 2011.
[10] M. M. Michael. Hazard pointers: Safe memory
reclamation for lock-free objects. IEEE Trans. Parallel
Distrib. Syst., 15(6):491{504, 2004.
[11] M. M. Michael and M. L. Scott. Simple, fast, and
practical non-blocking and blocking concurrent queue
algorithms. In PODC, 1996.
[12] E. Petrank, M. Musuvathi, and B. Steensgaard.
Progress guarantee for parallel programs via bounded
lock-freedom. In PLDI, 2009.
[13] F. Pizlo, E. Petrank, and B. Steensgaard. A study of
concurrent real-time garbage collectors. In PLDI 2008.
_______________________________________________
Concurrency-interest mailing list
Concurrency-interest&amp;lt; at &amp;gt;cs.oswego.edu
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
&lt;/pre&gt;</description>
    <dc:creator>Kimo Crossman</dc:creator>
    <dc:date>2012-05-15T03:24:05</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9415">
    <title>Object finalization</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9415</link>
    <description>&lt;pre&gt;Hi,
I could not find any resources that I felt were clear and trustworthy
enough, so...

I would like to have confirmed (or busted) my assumption that the following
code is buggy, because the garbage collector might set the `a` field to
null, before this `finalize` method can read it, thus preventing the method
from attempting to cleanly dispose of the `Resource` in the `b` field —
this all under the assertion that `safelyDispose` itself never throws:

public class SomeService {
  private final Resource a, b;

  public SomeService(Resource a, Resource b) {
    assert a != null &amp;amp;&amp;amp; b != null;
    this.a = a;
    this.b = b;
  }
  &amp;lt; at &amp;gt;Override
  protected void finalize() throws Throwable {
    a.safelyDispose();
    b.safelyDispose();
  }
}

Cheers,
Chris
_______________________________________________
Concurrency-interest mailing list
Concurrency-interest&amp;lt; at &amp;gt;cs.oswego.edu
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
&lt;/pre&gt;</description>
    <dc:creator>Chris Vest</dc:creator>
    <dc:date>2012-05-13T20:22:21</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9414">
    <title>Hung progress in ThreadPoolExecutor ExecutorCompletionService when slave threads killed.</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9414</link>
    <description>&lt;pre&gt;Hi there.

I wrote a JUnit runner that attempts to annihilate any threads that
leaked out of a given test's scope. The process starts by setting an
interrupt flag, then after some delay it just calls Thread.stop()
(let's not go into why this particular method was chosen for now, I
realize the consequences).

Anyway. I've encountered an interesting scenario where a
ThreadPoolExecutor is used in combination with
ExecutorCompletionService (in Apache Lucene). What happens is that the
thread pool's threads are first interrupted (which doesn't terminate
thread pool threads, they are reused) and then stopped, which does
seem to kill them (I see uncaught stacks:

java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:155)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1260)
at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:460)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:449)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1043)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1103)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

and then the thread pool's pool is refilled with fresh threads.

Interestingly, any subsequent use of the executor completion service
deadlocks. I would assume the problem is somewhere in my code but this
happens only on Java 1.7, on 1.6 the execution proceeds normally with
those refilled threads. A stack trace of the hung process shows all
executor service threads parked on:

"LuceneTestCase-84-thread-10" prio=6 tid=0x00000000087a3800 nid=0x19a8
waiting on condition [0x000000000e00e000]
   java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  &amp;lt;0x00000000f92a0318&amp;gt; (a
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1043)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1103)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

and the main thread utilizing completion service is parked on the queue:

"TEST-TestScope-org.apache.lucene.search.TestPrefixInBooleanQuery.testTermBooleanQuery-seed#[10A1C9CC1F06B49B]"
prio=6 tid=0x0000000008798000 nid=0x1cbc waiting on condition
[0x000000000aebd000]
   java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  &amp;lt;0x00000000f94614c0&amp;gt; (a
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at java.util.concurrent.ExecutorCompletionService.take(ExecutorCompletionService.java:193)
at org.apache.lucene.search.IndexSearcher$ExecutionHelper.next(IndexSearcher.java:756)
        ...

The completion service has submitted tasks, they're just not executed.
This in fact is a deadlock state.

Any hints/ ideas what might have changed in between 1.6 and 1.7 that
may be causing this? I couldn't reproduce on a small example but the
above scenario is 100% reproducible (well, on my machine and Java
1.7.0_03-b05).

Thanks,
Dawid
&lt;/pre&gt;</description>
    <dc:creator>Dawid Weiss</dc:creator>
    <dc:date>2012-05-13T20:08:31</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9392">
    <title>CallerRunsOrRejects for JDK8?</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9392</link>
    <description>&lt;pre&gt;Hey,

How about this for inclusion in JDK8?

/**
 * The RejectedExecutionHandler used by Akka, it improves on
CallerRunsPolicy
 * by throwing a RejectedExecutionException if the executor isShutdown.
 * (CallerRunsPolicy silently discards the runnable in this case, which is
arguably broken)
 */
class CallerRunsOrRejects extends RejectedExecutionHandler {
  def rejectedExecution(runnable: Runnable, threadPoolExecutor:
ThreadPoolExecutor): Unit = {
    if (threadPoolExecutor.isShutdown) throw new
RejectedExecutionException("Shutdown")
    else runnable.run()
  }
}

Cheers,
√

&lt;/pre&gt;</description>
    <dc:creator>√iktor Ҡlang</dc:creator>
    <dc:date>2012-05-12T16:39:49</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9375">
    <title>Quest for the optimal queue</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9375</link>
    <description>&lt;pre&gt;Hey guys,

I'd like to explore alternatives to ConcurrentLinkedQueue, especially to
get a bit lower latency and perhaps even lower mem usage.

Behavior:
No locks
Unbounded
Single consumer
Multiple producers

Operations:

dequeue
enqueue
numberOfMessages // Would be nice to have as a constant, can be linear or
simply not supported, doesn't really matter
hasMessages // Just a Boolean if there's anything in there at all, only
needs to return true if something has been put in that hasn't been pulled
out yet

Is there anything out there which is better than CLQ?

Cheers,
√

&lt;/pre&gt;</description>
    <dc:creator>√iktor Ҡlang</dc:creator>
    <dc:date>2012-05-11T15:00:21</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9363">
    <title>Class striped/ordered Thread Pool</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9363</link>
    <description>&lt;pre&gt;Hello all,

I'm looking for a thread pool with the following characteristics... (in 
pseudo-code)

interface StripedRunner {
     Object getStripeClass();
     void run();
}

magicPool.execute( stripedRunner );

The idea being that any StripedRunners with the same stripeClass would 
get executed in the order they were queued,
but StripedRunners with different stripedClasses could execute 
independently.

Is there a way to configure the standard concurrent pools to work this 
way (doesn't seem to be), or a way to extends
the current code?

Or perhaps some third party library implementation?

Thanks!

Glenn McGregor

_______________________________________________
Concurrency-interest mailing list
Concurrency-interest&amp;lt; at &amp;gt;cs.oswego.edu
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
&lt;/pre&gt;</description>
    <dc:creator>Glenn McGregor</dc:creator>
    <dc:date>2012-05-11T04:53:46</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9334">
    <title>ForkJoinPool for async http calls?</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9334</link>
    <description>&lt;pre&gt;Sorry if this is a stupid question regarding fork-join pools, but I am not
sure wheter the "lightweigth future" idea would also work async http calls.
(And please also excuse my bad english)

Currently I use the ning asnyc-http-client (
https://github.com/sonatype/async-http-client) in an event-driven callback
style to do nonblocking http-calls from a servlet.

However the callback style gets a bit complicated when the program-logic
gets complex so I wonder wheter I could use ForkJoinTask to transfer the
callback style to non-thread-blocking futures.

The idea is to initialize the nonblocking HttpCall in ForkJoinTaks.exec()
and when the callback receives the http-response it calls the
ForkJoinTaks.complete() method.

Maybe someone can take a look at the following ForkJoinTask which wraps an
HttpCall and say wheter it is a reasonable use of ForkJoinPool.

import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.Response;

//The forkjoin task which wraps an async-http-call
class HttpTask extends ForkJoinTask&amp;lt;Response&amp;gt; {

private Response result;
private AsyncHttpClient.BoundRequestBuilder httpRequestBuilder;
 public HttpTask(AsyncHttpClient.BoundRequestBuilder builder) {
//the httpRequestBuilder is setup up by the caller (setting the url etc)
        //and used by HttpTask to execute the http request
        this.httpRequestBuilder = builder;
}
 &amp;lt; at &amp;gt;Override
protected boolean exec() {
try {
//this is non blocking event-style http call
httpRequestBuilder.execute(new AsyncCompletionHandler&amp;lt;Response&amp;gt;() {

&amp;lt; at &amp;gt;Override
public Response onCompleted(Response resp) throws Exception {
//when the response is received complete the ForkJoinTask
HttpTask.this.complete(resp);
return resp;
}
 &amp;lt; at &amp;gt;Override
public void onThrowable(Throwable t) {
//wehn exception complete Exceptionally the ForkJoinTask
HttpTask.this.completeExceptionally(t);
}
 });
} catch (IOException e) {
throw new RuntimeException(e);
}
return false;
}

&amp;lt; at &amp;gt;Override
public Response getRawResult() {
return result;
}

&amp;lt; at &amp;gt;Override
protected void setRawResult(Response arg0) {
result = arg0;
}
}

I than use the HttpTask in Servelt like that:

public class FooServlet extends javax.servlet.http.HttpServlet {

private ForkJoinPool forJoinPool = new ForkJoinPool();
private AsyncHttpClient httpClient = new AsyncHttpClient();
&amp;lt; at &amp;gt;Override
protected void doGet(final HttpServletRequest req, final
HttpServletResponse resp)
throws ServletException, IOException {
final AsyncContext asyncCtxt = req.getAsyncContext();
RecursiveAction action = new RecursiveAction() {
 &amp;lt; at &amp;gt;Override
protected void compute() {
//do the http request
HttpTask t = new HttpTask(httpClient.prepareGet("http//url.to.service/"));
    Response res = t.invoke();
 }
};
}
}

My assumption here is that when the HttpTask is invoked that the
ForkJoinPool does not block the thread until the Response is received but
rather takes another RecursiveAtion to process another request until the
httpresponse arrives.

My question is wheter my assumptions are right and wheter this is a
reasonable use of ForkJoinPool.

Thanks for any responses.
_______________________________________________
Concurrency-interest mailing list
Concurrency-interest&amp;lt; at &amp;gt;cs.oswego.edu
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
&lt;/pre&gt;</description>
    <dc:creator>Christian Essl</dc:creator>
    <dc:date>2012-05-06T21:58:23</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9328">
    <title>Intel's HLE and Java</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9328</link>
    <description>&lt;pre&gt;I've been thinking about what to do with Intel's Hardware Lock Elision
(HLE), if anything.

Briefly, HLE allows locked regions to proceed transactionally,
so something like Hashtable's

    public synchronized V put(K key, V value) {
        ...
    }

could proceed in parallel with other cores accessing the same
Hashtable, as long as there were no conflict with the same hash slot.
If any unsafe instructions (interrupts, I/O, etc.) were executed or if
there were a conflict with another thread, the hardware would abort the
transaction (i.e. discard all pending memory updates and automagically
fall back to locking).  If there were no conflict, all threads would
proceed in parallel, and all accesses to the lock would be elided.

In theory this could be used for Java.  There is, as far as I can see,
one significant downside: if conflicts are highly probable, there will
be a performance degradation because speculation on transactions that
will abort wastes CPU cycles.

Also, I was worried that this might not actually respect the JMM
because on the x86, a StoreLoad barrier requires some sort of fence,
such as MFENCE.  However, according to the Intel documentation MFENCE
is allowed in a transaction and will not abort, so I think we're OK.

To handle the performance worry, a JIT could use some kind of cost
measure (length, number of memory accesses, etc.) to determine whether
to use HLE, on the assumption that short transactions are unlikely to
abort.  But this doesn't actually tell us what we need to know, which
is whether a conflict is likely.  Only the programmer knows that, and
even short transactions might abort if they are very frequent.

We could create a family of HLE-enabled locks and leave it all to the
programmer, but this seems like a lot of work and means that this
potentially very useful option will be wasted.  It also means a lot
of bloat in j.u.c.

Thoughts welcome...

Andrew.


Intel® Architecture Instruction Set Extensions Programming Reference
http://software.intel.com/file/41604/319433-012a.pdf
&lt;/pre&gt;</description>
    <dc:creator>Andrew Haley</dc:creator>
    <dc:date>2012-04-25T11:35:25</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9287">
    <title>Proper workaround for FutureTask.set()/get()race (CR 7132378)</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9287</link>
    <description>&lt;pre&gt;Hi guys,

I'm trying to workaround the FutureTask race described in CR 7132378:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7132378

I do realize the fix is already there in Doug's code, but both waiting
for JDK update or bootclasspath-ing jsr166.jar is not an option for this
particular case I'm dealing with.

Hence, my question is: can this code be considered a proper workaround?

/**
 * Specialized form of future allowing to set the result.
 *
 * &amp;lt; at &amp;gt;param &amp;lt;V&amp;gt;
 */
public class SettableFuture&amp;lt;V&amp;gt; extends FutureTask&amp;lt;V&amp;gt; {

    /**
     * Implementation notes:
     *
     * This implementation also accounts for known bug in FutureTask:
     * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7132378
     *
     * We compensate for possible race by making sure set() had
     * completed before returning from get(). Since get() is
     * blocking operation, we first wait without any synchronization,
     * and then do get() again synchronizing with set() to make sure
     * set() had indeed completed.
     *
     * This bails out earlier on exception or if the timeout had
     * expired.
     */

    /**
     * Dummy callable so that underlying implementation
     * will not complain.
     */
    private static final Callable DUMMY = new Callable() {
        &amp;lt; at &amp;gt;Override
        public Object call() throws Exception {
            throw new IllegalStateException("Trying to read from dummy
callable in SettableFuture");
        }
    };

    public SettableFuture() {
        super(DUMMY);
    }

    &amp;lt; at &amp;gt;Override
    public void set(V v) {
        synchronized (this) {
            super.set(v);
        }
    }

    &amp;lt; at &amp;gt;Override
    protected void setException(Throwable t) {
        synchronized (this) {
            super.setException(t);
        }
    }

    &amp;lt; at &amp;gt;Override
    public V get() throws InterruptedException, ExecutionException {
        super.get();
        synchronized (this) {
            return super.get();
        }
    }

    &amp;lt; at &amp;gt;Override
    public V get(long timeout, TimeUnit unit) throws
InterruptedException, ExecutionException, TimeoutException {
        super.get(timeout, unit);
        synchronized (this) {
            return super.get();
        }
    }
}

Thanks,
Aleksey.
&lt;/pre&gt;</description>
    <dc:creator>Aleksey Shipilev</dc:creator>
    <dc:date>2012-04-20T08:29:57</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9284">
    <title>Work-stealing ThreadPool</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9284</link>
    <description>&lt;pre&gt;Hi guys,

There are multiple cases now when people are choosing ForkJoinPool over
regular ThreadPoolExecutor because of improved submission throughput and
work balancing. Can we embrace this fact and do proper isolation in API
for this cases?

I'm thinking public class j.u.c.WorkStealingExecutor implementing
ExecutorService, but delegating directly to ForkJoinPool. If that is
added to JDK7/JDK8, we can properly isolate these customers from
exposing FJP underneath. Moreover, after this API is exposed, we can
gradually replace FJP delegation with independent work-stealing
executor, if ties with FJP will bother anyone.

Are there any troubles with this proposal I missed?

-Aleksey.
&lt;/pre&gt;</description>
    <dc:creator>Aleksey Shipilev</dc:creator>
    <dc:date>2012-04-19T15:14:59</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9272">
    <title>Composing multiple tasks into a singleFuture/FutureTask</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9272</link>
    <description>&lt;pre&gt;Hi all,

I have been looking for the right way to build an API that returns a
Future that is composed of tasks that will be performed in multiple
stages, potentially from more than one thread.

My use cases is a disk based persistence store. The initial put API
call creates a task that compresses and checksums the payload. The
resulting Future is bound in a Runnable and submitted to a single
thread ExecutorService that timestamps the entry and appends it to a
file and it is the Future of the second task that is currently returned
by the API.

 The trick is that the Future that is returned by the put call should
 not complete until the write is durable. Writes are made durable by
 periodically invoking fsync from a dedicated thread or by rotating
 write threads as each blocks on fsync/force. This allows for group
 commit at an interval the IO device can handle without killing
 throughput.

Ideally I could create a FutureTask that is composed of several other
Futures, some of which will not exist when the FutureTask is initially
created and returned by the API. I do know how many dependencies there
will be
expected up front.

If I had such a thing I would create a task to do the fsync and add it
as the last dependency to every Future read by the put API call.

This would be a lot easier if I were willing to have many threads
standing around blocking on Futures, but that rubs me the wrong way. It
isn't fun to jstack and see all the noise.

I suspect that there is something in Guava
com.google.common.util.concurrent.Futures to handle this case, but it
isn't jumping out at me.

Thanks,
Ariel Weisberg
&lt;/pre&gt;</description>
    <dc:creator>Ariel Weisberg</dc:creator>
    <dc:date>2012-04-17T15:39:56</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9260">
    <title>ForkJoinPool seems lead to a worse latencythan traditional ExecutorServices</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9260</link>
    <description>&lt;pre&gt;Hi, all,

I tried to use  the newest version of  ForkJoinPool from the cvs repository
of jsr166y to replace the old  ExecutorService on our RPC project
opensource at http://code.google.com/p/nfs-rpc/ .

The modification is quite slight. Here is the diff

Index:
nfs-rpc-common/src/main/java/code/google/nfs/rpc/NamedForkJoinThreadFactory.java
===================================================================
---
nfs-rpc-common/src/main/java/code/google/nfs/rpc/NamedForkJoinThreadFactory.java
(revision
0)
+++
nfs-rpc-common/src/main/java/code/google/nfs/rpc/NamedForkJoinThreadFactory.java
(revision
0)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,48 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+package code.google.nfs.rpc;
+/**
+ * nfs-rpc
+ *   Apache License
+ *
+ *   http://code.google.com/p/nfs-rpc (c) 2011
+ */
+import java.util.concurrent.atomic.AtomicInteger;
+
+import code.google.nfs.rpc.jsr166y.ForkJoinPool;
+import
code.google.nfs.rpc.jsr166y.ForkJoinPool.ForkJoinWorkerThreadFactory;
+import code.google.nfs.rpc.jsr166y.ForkJoinWorkerThread;
+
+/**
+ * Helper class to let user can monitor worker threads.
+ *
+ * &amp;lt; at &amp;gt;author &amp;lt;a href="mailto:coderplay&amp;lt; at &amp;gt;gmail.com"&amp;gt;coderplay&amp;lt;/a&amp;gt;
+ */
+public class NamedForkJoinThreadFactory implements
ForkJoinWorkerThreadFactory {
+
+ static final AtomicInteger poolNumber = new AtomicInteger(1);
+
+    final AtomicInteger threadNumber = new AtomicInteger(1);
+    final String namePrefix;
+    final boolean isDaemon;
+
+    public NamedForkJoinThreadFactory() {
+        this("pool");
+    }
+    public NamedForkJoinThreadFactory(String name) {
+        this(name, false);
+    }
+    public NamedForkJoinThreadFactory(String preffix, boolean daemon) {
+        namePrefix = preffix + "-" + poolNumber.getAndIncrement() +
"-thread-";
+        isDaemon = daemon;
+    }
+
+    &amp;lt; at &amp;gt;Override
+    public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
+        ForkJoinWorkerThread t =
+
 ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
+        t.setName(namePrefix + threadNumber.getAndIncrement());
+        t.setDaemon(isDaemon);
+        return t;
+    }
+
+}
+
Index:
nfs-rpc-common/src/main/java/code/google/nfs/rpc/benchmark/AbstractBenchmarkServer.java
===================================================================
---
nfs-rpc-common/src/main/java/code/google/nfs/rpc/benchmark/AbstractBenchmarkServer.java
(revision
120)
+++
nfs-rpc-common/src/main/java/code/google/nfs/rpc/benchmark/AbstractBenchmarkServer.java
(working
copy)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -8,12 +8,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;

-import code.google.nfs.rpc.NamedThreadFactory;
+import code.google.nfs.rpc.NamedForkJoinThreadFactory;
+import code.google.nfs.rpc.jsr166y.ForkJoinPool;
+import
code.google.nfs.rpc.jsr166y.ForkJoinPool.ForkJoinWorkerThreadFactory;
 import code.google.nfs.rpc.protocol.PBDecoder;
 import code.google.nfs.rpc.protocol.RPCProtocol;
 import code.google.nfs.rpc.protocol.SimpleProcessorProtocol;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -66,9 +64,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
  });
  server.registerProcessor(RPCProtocol.TYPE, "testservice", new
BenchmarkTestServiceImpl(responseSize));
  server.registerProcessor(RPCProtocol.TYPE, "testservicepb", new
PBBenchmarkTestServiceImpl(responseSize));
- ThreadFactory tf = new NamedThreadFactory("BUSINESSTHREADPOOL");
- ExecutorService threadPool = new ThreadPoolExecutor(20, maxThreads,
- 300, TimeUnit.SECONDS, new SynchronousQueue&amp;lt;Runnable&amp;gt;(), tf);
+ ForkJoinWorkerThreadFactory tf = new
NamedForkJoinThreadFactory("BUSINESSTHREADPOOL");
+ ExecutorService threadPool = new ForkJoinPool(maxThreads, tf,
+          new Thread.UncaughtExceptionHandler() {
+              public void uncaughtException(Thread t, Throwable e){
+                // do nothing;
+              };
+          }, true);
  server.start(listenPort, threadPool);
  }


I did a benchmark (see
http://code.google.com/p/nfs-rpc/wiki/HowToRunBenchmark ) with the hope of
significant TPS improvments, but got a bad result cross to the purpose.
 ForkJoinPool (avg response time 12 ms) seems lead to a worse latency than
it did with traditional ExecutorService (avg response time 3ms).

With ForkJoinPool:

----------Benchmark Statistics--------------
 Concurrents: 500
 CodecType: 3
 ClientNums: 1
 RequestSize: 100 bytes
 Runtime: 120 seconds
 Benchmark Time: 81
 Requests: 3740311 Success: 99% (3739274) Error: 0% (1037)
 Avg TPS: 41374 Max TPS: 62881 Min TPS: 3333
 Avg RT: 12ms
 RT &amp;lt;= 0: 0% 1829/3740311
 RT (0,1]: 1% 59989/3740311
 RT (1,5]: 47% 1778386/3740311
 RT (5,10]: 17% 655377/3740311
 RT (10,50]: 32% 1204205/3740311
 RT (50,100]: 0% 31479/3740311
 RT (100,500]: 0% 546/3740311
 RT (500,1000]: 0% 7463/3740311
 RT &amp;gt; 1000: 0% 1037/3740311


With traditional thread pool:
----------Benchmark Statistics--------------
 Concurrents: 500
 CodecType: 3
 ClientNums: 1
 RequestSize: 100 bytes
 Runtime: 120 seconds
 Benchmark Time: 81
 Requests: 12957281 Success: 100% (12957281) Error: 0% (0)
 Avg TPS: 144261 Max TPS: 183390 Min TPS: 81526
 Avg RT: 3ms
 RT &amp;lt;= 0: 0% 3997/12957281
 RT (0,1]: 4% 592905/12957281
 RT (1,5]: 95% 12312500/12957281
 RT (5,10]: 0% 19280/12957281
 RT (10,50]: 0% 92/12957281
 RT (50,100]: 0% 507/12957281
 RT (100,500]: 0% 26500/12957281
 RT (500,1000]: 0% 1500/12957281
 RT &amp;gt; 1000: 0% 0/12957281


I ran this benchmark on two 16 cores Westmere machines ( Xeon E5620 8 core
HT) with the same configuration below of the two tests.

1. JDK version: Oracle 1.7.0_03 (hotspot)

2. client side JVM options:
-Xms4g -Xmx4g -Xmn1g -XX:+PrintGCDetails -XX:+PrintGCDateStamps
-Xloggc:gc.log -Dwrite.statistics=true -XX:+UseParallelGC
-XX:+UseCondCardMark -XX:-UseBiasedLocking
-Djava.ext.dirs=/home/min/nfs-rpc
code.google.nfs.rpc.netty.benchmark.NettySimpleBenchmarkClient 10.232.98.96
8888 500 1000 3 100 120 1

3. server side JVM options:
-Xms2g -Xmx2g -Xmn500m -XX:+UseParallelGC -XX:+PrintGCDetails
-XX:+PrintGCDateStamps -Xloggc:gc.log -XX:+UseCondCardMark
-XX:-UseBiasedLocking -Djava.ext.dirs=/home/min/nfs-rpc
code.google.nfs.rpc.netty.benchmark.NettyBenchmarkServer 8888 100 100

Low context switches, about 8000 per second, is also observed with
ForkJoinPool against to which with the old threadpool it's about 150000.
Benchmarks under Oracle JDK 1.6 is also did by me with similar results.

Is there anyone kindly explain the reason why leading to those describe
above for me ?

Thanks,
Min

&lt;/pre&gt;</description>
    <dc:creator>Min Zhou</dc:creator>
    <dc:date>2012-04-17T10:30:17</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9242">
    <title>(no subject)</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9242</link>
    <description>&lt;pre&gt;Hi All,
 
I have found a way of preventing deadlocks in java. The methodology(which is code) completely prevents the deadlock from accuring by detecting it in advance. This can be used across the systems seamlessly. 
 
Kindly let me know what I need to do next. I want this to be part of next jdk release.
 
Thanks &amp;amp; Regards,
Rohit Kumar_______________________________________________
Concurrency-interest mailing list
Concurrency-interest&amp;lt; at &amp;gt;cs.oswego.edu
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
&lt;/pre&gt;</description>
    <dc:creator>Rohit Kumar</dc:creator>
    <dc:date>2012-04-16T11:03:59</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9232">
    <title>CountedCompleters</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9232</link>
    <description>&lt;pre&gt;
After sitting on multiple variations for months, I committed
CountedCompleter, a completion-based flavor of ForkJoinTask.

As mentioned a few times over the past year, the main motivation
is to better support tasks that perform IO or other base
actions that may (or may not) take a lot of time to execute.
As is the case with JDK7 async IO and other completion-based
frameworks, the most common path to efficiency is for such tasks
to arrange continuation actions that occur upon their completion.
The main twist for CountedCompleters is that continuations
might be dependent on multiple actions, not just one. (Or in
other words, the continuations must be preceded by a specialized,
"bottom-up" form of join.)

The CountedCompleter abstract class provides a minimal basis
for these kinds of tasks. While some of the mechanics are
reminiscent of other FJ-like frameworks such as Intel TBB,
CountedCompleters are designed to fit smoothly with other
kinds of ForkJoinTasks (like RecursiveActions), and so still
allow people to use the more pleasant Future-style conventions
rather than count-based bottom-up joining unless they need them.
At the same time, the CountedCompleter class exposes enough
mechanics to allow all sorts of tweaks that people can use
to improve performance.
In particular, in addition to usually being the best way to deal
with IO etc bound tasks, CountedCompleters sometimes fare better
than RecursiveActions in programs that entail lots of garbage
collection because GC can have similar impact on task variability.

Even though targeted for JDK8, versions of CountedCompleter
appear in the jsr166y and main repositories, not jsr166e. This is
because they require a non-public hook into modified ForkJoinTask
exception handling mechanics in order to properly propagate
exceptional completions. For sources, docs, and jar files, see
the usual links at http://gee.cs.oswego.edu/dl/concurrency-interest/index.html

The API docs include more details and some examples:
http://gee.cs.oswego.edu/dl/jsr166/dist/docs/java/util/concurrent/CountedCompleter.html

I also added a few (with more to come) test/demo programs that illustrate
other usages. See CCBoxedLongSort and CCJacobi in
http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/test/loops/

Please try these out. As always, comments and suggestions
(hopefully based on usage experience) would be welcome.

-Doug
&lt;/pre&gt;</description>
    <dc:creator>Doug Lea</dc:creator>
    <dc:date>2012-04-09T14:16:01</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9219">
    <title>ConcurrentLinkedQueue in Java 5 vs. 6</title>
    <link>http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/9219</link>
    <description>&lt;pre&gt;Hi,

Running some benchmarks on a multicore machine (Ultra SPARC T2),
I noticed a significant improvement in performance
of ConcurrentLinkedQueue in Java 6 (1.6.0_23) over Java 5 (1.5.0_14).
 The improvement in high contention scenarios is in a factor of up to 5
times!

I'm curious about the reason for this improvement, as the basic algorithm
is the same (MS queue)...
Examining both of the source files, I noticed that in Java 6 version
there's a use in lazySet in some places,
and direct usage of Unsafe class, instead of AtomicReferenceFieldUpdater in
java 5.

But could this explain the significant improvement, or are there other key
chages?


Thanks in advance,
---
Best Regards,
Ilya Mirsky
&amp;lt;http://www.cs.bgu.ac.il/~mirskyil/&amp;gt;  &amp;lt;http://il.linkedin.com/in/ilyamirsky&amp;gt;
   &amp;lt;https://www.facebook.com/ilya.mirsky&amp;gt;
_______________________________________________
Concurrency-interest mailing list
Concurrency-interest&amp;lt; at &amp;gt;cs.oswego.edu
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
&lt;/pre&gt;</description>
    <dc:creator>Ilya Mirsky</dc:creator>
    <dc:date>2012-04-07T17:45:57</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.comp.java.jsr.166-concurrency">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.comp.java.jsr.166-concurrency</link>
  </textinput>
</rdf:RDF>

