-
Bug
-
Resolution: Duplicate
-
P3
-
8u5
-
b88
-
x86
-
windows_7
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8142165 | emb-9 | Doug Lea | P3 | Resolved | Fixed | team |
FULL PRODUCT VERSION :
java version "1.8.0_05"
java<TM> SE Runtime Environment <build 1.8.0_05-b13>
Java HotSpot<TM> Client VM <build 25.5-b02, mixed mode, sharing>
A DESCRIPTION OF THE PROBLEM :
When we call the readLock method of StampedLockï¼If the thread is already in the interrupt statusï¼so even before obtaining the lock, the thread will always spin, which filled the CPU:
public class BugOfInterruptedThread {
public static void main(String[] args) throws InterruptedException{
final StampedLock lock = new StampedLock();
new Thread(){
public void run(){
long readLong = lock.writeLock();
LockSupport.parkNanos(6100000000L);
lock.unlockWrite(readLong);
}
}.start();
Thread.sleep(100);
for( int i = 0; i < 3; ++i)
new Thread(new OccupiedCPUReadThread(lock)).start();
}
private static class OccupiedCPUReadThread implements Runnable{
private StampedLock lock;
public OccupiedCPUReadThread(StampedLock lock){
this.lock = lock;
}
public void run(){
Thread.currentThread().interrupt();
long lockr = lock.readLock();
System.out.println(Thread.currentThread().getName() + " get read lock");
lock.unlockRead(lockr);
}
}
}
Execute the above code, three cores are filled in six seconds of time.
The reason is that when readLock method detects the interrupt is not cleared and saved (and later restored) interrupt.
REGRESSION. Last worked in version 8u5
ADDITIONAL REGRESSION INFORMATION:
java version "1.8.0_05"
java<TM> SE Runtime Environment <build 1.8.0_05-b13>
Java HotSpot<TM> Client VM <build 25.5-b02, mixed mode, sharing>
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Perform the following code, observe CPU usageï¼
public class BugOfInterruptedThread {
public static void main(String[] args) throws InterruptedException{
final StampedLock lock = new StampedLock();
new Thread(){
public void run(){
long readLong = lock.writeLock();
LockSupport.parkNanos(6100000000L);
lock.unlockWrite(readLong);
}
}.start();
Thread.sleep(100);
for( int i = 0; i < 3; ++i)
new Thread(new OccupiedCPUReadThread(lock)).start();
}
private static class OccupiedCPUReadThread implements Runnable{
private StampedLock lock;
public OccupiedCPUReadThread(StampedLock lock){
this.lock = lock;
}
public void run(){
Thread.currentThread().interrupt();
long lockr = lock.readLock();
System.out.println(Thread.currentThread().getName() + " get read lock");
lock.unlockRead(lockr);
}
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Before acquiring the lock, the thread hangs.
ACTUAL -
Before acquiring the lock, the thread always occupy CPU.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class BugOfInterruptedThread {
public static void main(String[] args) throws InterruptedException{
final StampedLock lock = new StampedLock();
new Thread(){
public void run(){
long readLong = lock.writeLock();
LockSupport.parkNanos(6100000000L);
lock.unlockWrite(readLong);
}
}.start();
Thread.sleep(100);
for( int i = 0; i < 3; ++i)
new Thread(new OccupiedCPUReadThread(lock)).start();
}
private static class OccupiedCPUReadThread implements Runnable{
private StampedLock lock;
public OccupiedCPUReadThread(StampedLock lock){
this.lock = lock;
}
public void run(){
Thread.currentThread().interrupt();
long lockr = lock.readLock();
System.out.println(Thread.currentThread().getName() + " get read lock");
lock.unlockRead(lockr);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Instead of using ReentrantReadWriteLock.
java version "1.8.0_05"
java<TM> SE Runtime Environment <build 1.8.0_05-b13>
Java HotSpot<TM> Client VM <build 25.5-b02, mixed mode, sharing>
A DESCRIPTION OF THE PROBLEM :
When we call the readLock method of StampedLockï¼If the thread is already in the interrupt statusï¼so even before obtaining the lock, the thread will always spin, which filled the CPU:
public class BugOfInterruptedThread {
public static void main(String[] args) throws InterruptedException{
final StampedLock lock = new StampedLock();
new Thread(){
public void run(){
long readLong = lock.writeLock();
LockSupport.parkNanos(6100000000L);
lock.unlockWrite(readLong);
}
}.start();
Thread.sleep(100);
for( int i = 0; i < 3; ++i)
new Thread(new OccupiedCPUReadThread(lock)).start();
}
private static class OccupiedCPUReadThread implements Runnable{
private StampedLock lock;
public OccupiedCPUReadThread(StampedLock lock){
this.lock = lock;
}
public void run(){
Thread.currentThread().interrupt();
long lockr = lock.readLock();
System.out.println(Thread.currentThread().getName() + " get read lock");
lock.unlockRead(lockr);
}
}
}
Execute the above code, three cores are filled in six seconds of time.
The reason is that when readLock method detects the interrupt is not cleared and saved (and later restored) interrupt.
REGRESSION. Last worked in version 8u5
ADDITIONAL REGRESSION INFORMATION:
java version "1.8.0_05"
java<TM> SE Runtime Environment <build 1.8.0_05-b13>
Java HotSpot<TM> Client VM <build 25.5-b02, mixed mode, sharing>
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Perform the following code, observe CPU usageï¼
public class BugOfInterruptedThread {
public static void main(String[] args) throws InterruptedException{
final StampedLock lock = new StampedLock();
new Thread(){
public void run(){
long readLong = lock.writeLock();
LockSupport.parkNanos(6100000000L);
lock.unlockWrite(readLong);
}
}.start();
Thread.sleep(100);
for( int i = 0; i < 3; ++i)
new Thread(new OccupiedCPUReadThread(lock)).start();
}
private static class OccupiedCPUReadThread implements Runnable{
private StampedLock lock;
public OccupiedCPUReadThread(StampedLock lock){
this.lock = lock;
}
public void run(){
Thread.currentThread().interrupt();
long lockr = lock.readLock();
System.out.println(Thread.currentThread().getName() + " get read lock");
lock.unlockRead(lockr);
}
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Before acquiring the lock, the thread hangs.
ACTUAL -
Before acquiring the lock, the thread always occupy CPU.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class BugOfInterruptedThread {
public static void main(String[] args) throws InterruptedException{
final StampedLock lock = new StampedLock();
new Thread(){
public void run(){
long readLong = lock.writeLock();
LockSupport.parkNanos(6100000000L);
lock.unlockWrite(readLong);
}
}.start();
Thread.sleep(100);
for( int i = 0; i < 3; ++i)
new Thread(new OccupiedCPUReadThread(lock)).start();
}
private static class OccupiedCPUReadThread implements Runnable{
private StampedLock lock;
public OccupiedCPUReadThread(StampedLock lock){
this.lock = lock;
}
public void run(){
Thread.currentThread().interrupt();
long lockr = lock.readLock();
System.out.println(Thread.currentThread().getName() + " get read lock");
lock.unlockRead(lockr);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Instead of using ReentrantReadWriteLock.
- backported by
-
JDK-8142165 Lack of save / restore interrupt mechanism undermines the StampedLock
- Resolved
- duplicates
-
JDK-8134855 Bulk integration of java.util.concurrent.locks classes
- Resolved