[concurrency-interest] RRWL with 'bad' Thread.getId() implementations

william.louth at jinspired.com william.louth at jinspired.com
Tue Jun 25 15:03:50 EDT 2013


I believe the (old) OC4J container did in fact override this method in Thread subclasses it used for request processing and returned a different int value. Many of us had to work around this by accessing the field itself through reflection.

I will give you one example in which one might consider overriding this value: a simulated playback of a metered software execution recording. Here having the threads ID match across process runs (and playbacks) would be extremely useful in comparing the playback with other less useful data collection approaches such as logging.

We eventually discounted this approach when we started thinking about near real-time playback of multiple JVM's within a single JVM which is exactly what Simz (http://www.jinspired.com/products/simz) offers today. Instead opting for a standardized thread specific Environment interface (across offline/online playbacks) in which we could lookup the id as well as the server id.

http://www.jinspired.com/site/plugin-to-the-matrix-for-virtual-machines-simulated-threads-stacks

>-----Original Message-----
>From: Nathan Reynolds [mailto:nathan.reynolds at oracle.com]
>Sent: Tuesday, June 25, 2013 08:02 PM
>To: 'Chris Dennis'
>Cc: concurrency-interest at cs.oswego.edu
>Subject: Re: [concurrency-interest] RRWL with 'bad' Thread.getId()	implementations
>
>Wow!  Final getId() would break user code?  Interesting.  Are there any 
>examples?  I can dream up a few but I am curious what is out in the wild.
>
>I guess we need another method in Thread which is declared final and 
>returns the "tid" member variable value.  Maybe it could be called 
>getFinalId(), getImmutableId(), getFirmId(), or getStableId().
>
>Nathan Reynolds 
><http://psr.us.oracle.com/wiki/index.php/User:Nathan_Reynolds> | 
>Architect | 602.333.9091
>Oracle PSR Engineering <http://psr.us.oracle.com/> | Server Technology
>On 6/25/2013 10:56 AM, Chris Dennis wrote:
>> The issue about getId() not being final has been thrown about forever 
>> – it's not going to be fixed because it would cause too much breakage 
>> in user code.  Seems strange to me though given that we know the non 
>> finality of getId allows users to do this, we aren't avoiding relying 
>> on that method – why don't we have some other way for library code 
>> (JDK or third-party) to get access to a unique identifier for a thread?
>>
>> On 6/25/13 1:24 PM, "Nathan Reynolds" <nathan.reynolds at oracle.com 
>> <mailto:nathan.reynolds at oracle.com>> wrote:
>>
>> The JavaDoc for Thread.getId() says "...thread ID is unique..." so I 
>> don't think this is a bug in RRWL.  Maybe Thread.getId() should be 
>> declared final.
>>
>> We might want to consider going as far as declaring the member field 
>> "tid" as final.  This could be done via "private long tid = 
>> nextThreadID();"
>>
>> I find it very interesting that threadInitNumber and threadSeqNumber 
>> are both used in the Thread class.  It seems we only need 1.  It seems 
>> that the constructor should use "Thread-" + tid for a thread name.  In 
>> fact, the name could read "Thread-10" and the tid could be 7 because 
>> there is a race between when the name is generated and the tid is 
>> set.  The mismatch probably doesn't matter functionally.  However, it 
>> could make it easier for debugging.
>>
>> Nathan Reynolds 
>> <http://psr.us.oracle.com/wiki/index.php/User:Nathan_Reynolds> | 
>> Architect | 602.333.9091
>> Oracle PSR Engineering <http://psr.us.oracle.com/> | Server Technology
>> On 6/25/2013 9:50 AM, Chris Dennis wrote:
>>> Hi All,
>>>
>>> While dealing with a customer issue, I ran in to the possibility of
>>> breaking a RRWL by feeding in Thread instances with colliding thread-ids.
>>> Inside RRWL the cachedHoldCounter logic assumes that getId() will return a
>>> unique identifier for a thread.  Do people consider this a bug in RRWL or
>>> not? (I think it would be agreed that this is also a bug in the
>>> subclassing of Thread)
>>>
>>> Regards,
>>>
>>> Chris Dennis
>>>
>>> public static void main(String[] args) {
>>>    final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
>>>    final CyclicBarrier barrier = new CyclicBarrier(2);
>>>      
>>>    Thread t1 = new EvilThread() {
>>>      public void run() {
>>>        try {
>>>          lock.readLock().lock();
>>>          barrier.await();
>>>          //T2 locks
>>>          barrier.await();
>>>          //T3 locks
>>>          //T3 unlocks
>>>          barrier.await();
>>>          //T2 unlocks
>>>          barrier.await();
>>>          lock.readLock().unlock();
>>>        } catch (Exception e) {
>>>          e.printStackTrace();
>>>        }
>>>      }
>>>        
>>>    };
>>>    Thread t2 = new EvilThread() {
>>>      public void run() {
>>>        try {
>>>          //T1 locks
>>>                    barrier.await();
>>>                    lock.readLock().lock();
>>>                    barrier.await();
>>>                    //T3 locks
>>>                    //T3 unlocks
>>>                    barrier.await();
>>>                    lock.readLock().unlock();
>>>                    barrier.await();
>>>                    //T1 unlocks
>>>        } catch (Exception e) {
>>>          e.printStackTrace();
>>>        }
>>>      }
>>>        
>>>    };
>>>    Thread t3 = new EvilThread() {
>>>      public void run() {
>>>        try {
>>>          //T1 locks
>>>          barrier.await();
>>>                    //T2 locks
>>>                    barrier.await();
>>>                    lock.readLock().lock();
>>>                    lock.readLock().unlock();
>>>                    barrier.await();
>>>                    //T2 unlocks
>>>                    barrier.await();
>>>                    //T3 unlocks
>>>        } catch (Exception e) {
>>>          e.printStackTrace();
>>>        }
>>>      }
>>>        
>>>    };
>>>      
>>>    t1.start();
>>>    t2.start();
>>>    t3.start();
>>>    }
>>>
>>>    
>>>    static class EvilThread extends Thread {
>>>    public long getId() {
>>>      return 42L;
>>>    }
>>>    }
>>>
>>>
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> Concurrency-interest at cs.oswego.eduhttp://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>> _______________________________________________ Concurrency-interest 
>> mailing list Concurrency-interest at cs.oswego.edu 
>> <mailto:Concurrency-interest at cs.oswego.edu> 
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest 
>
>





More information about the Concurrency-interest mailing list