reentrantreadwritelocktest.java

来自「SRI international 发布的OAA框架软件」· Java 代码 · 共 1,422 行 · 第 1/3 页

JAVA
1,422
字号
/*
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/licenses/publicdomain
 * Other contributors include Andrew Wright, Jeffrey Hayes,
 * Pat Fisher, Mike Judd.
 */

import junit.framework.*;
import edu.emory.mathcs.backport.java.util.concurrent.locks.*;
import edu.emory.mathcs.backport.java.util.concurrent.*;
import java.io.*;
import java.util.*;

public class ReentrantReadWriteLockTest extends JSR166TestCase {
    public static void main(String[] args) {
	junit.textui.TestRunner.run (suite());
    }
    public static Test suite() {
	return new TestSuite(ReentrantReadWriteLockTest.class);
    }

    /**
     * A runnable calling lockInterruptibly
     */
    class InterruptibleLockRunnable implements Runnable {
        final ReentrantReadWriteLock lock;
        InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
        public void run() {
            try {
                lock.writeLock().lockInterruptibly();
            } catch(InterruptedException success){}
        }
    }


    /**
     * A runnable calling lockInterruptibly that expects to be
     * interrupted
     */
    class InterruptedLockRunnable implements Runnable {
        final ReentrantReadWriteLock lock;
        InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
        public void run() {
            try {
                lock.writeLock().lockInterruptibly();
                threadShouldThrow();
            } catch(InterruptedException success){}
        }
    }

    /**
     * Subclass to expose protected methods
     */
    static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
        PublicReentrantReadWriteLock() { super(); }
//        public Collection getQueuedThreads() {
//            return super.getQueuedThreads();
//        }
//        public Collection getWaitingThreads(Condition c) {
//            return super.getWaitingThreads(c);
//        }
    }

    /**
     * Constructor sets given fairness, and is in unlocked state
     */
    public void testConstructor() {
	ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
        assertFalse(rl.isFair());
        assertFalse(rl.isWriteLocked());
        assertEquals(0, rl.getReadLockCount());
//	ReentrantReadWriteLock r2 = new ReentrantReadWriteLock(true);
//        assertTrue(r2.isFair());
//        assertFalse(r2.isWriteLocked());
//        assertEquals(0, r2.getReadLockCount());
    }

    /**
     * write-locking and read-locking an unlocked lock succeed
     */
    public void testLock() {
	ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
        rl.writeLock().lock();
        assertTrue(rl.isWriteLocked());
        assertTrue(rl.isWriteLockedByCurrentThread());
        assertEquals(0, rl.getReadLockCount());
        rl.writeLock().unlock();
        assertFalse(rl.isWriteLocked());
        assertFalse(rl.isWriteLockedByCurrentThread());
        assertEquals(0, rl.getReadLockCount());
        rl.readLock().lock();
        assertFalse(rl.isWriteLocked());
        assertFalse(rl.isWriteLockedByCurrentThread());
        assertEquals(1, rl.getReadLockCount());
        rl.readLock().unlock();
        assertFalse(rl.isWriteLocked());
        assertFalse(rl.isWriteLockedByCurrentThread());
        assertEquals(0, rl.getReadLockCount());
    }


//    /**
//     * locking an unlocked fair lock succeeds
//     */
//    public void testFairLock() {
//	ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true);
//        rl.writeLock().lock();
//        assertTrue(rl.isWriteLocked());
//        assertTrue(rl.isWriteLockedByCurrentThread());
//        assertEquals(0, rl.getReadLockCount());
//        rl.writeLock().unlock();
//        assertFalse(rl.isWriteLocked());
//        assertFalse(rl.isWriteLockedByCurrentThread());
//        assertEquals(0, rl.getReadLockCount());
//        rl.readLock().lock();
//        assertFalse(rl.isWriteLocked());
//        assertFalse(rl.isWriteLockedByCurrentThread());
//        assertEquals(1, rl.getReadLockCount());
//        rl.readLock().unlock();
//        assertFalse(rl.isWriteLocked());
//        assertFalse(rl.isWriteLockedByCurrentThread());
//        assertEquals(0, rl.getReadLockCount());
//    }

    /**
     * getWriteHoldCount returns number of recursive holds
     */
    public void testGetHoldCount() {
	ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	for(int i = 1; i <= SIZE; i++) {
	    lock.writeLock().lock();
	    assertEquals(i,lock.getWriteHoldCount());
	}
	for(int i = SIZE; i > 0; i--) {
	    lock.writeLock().unlock();
	    assertEquals(i-1,lock.getWriteHoldCount());
	}
    }


    /**
     * write-unlocking an unlocked lock throws IllegalMonitorStateException
     */
    public void testUnlock_IllegalMonitorStateException() {
	ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
	try {
	    rl.writeLock().unlock();
	    shouldThrow();
	} catch(IllegalMonitorStateException success){}
    }


    /**
     * write-lockInterruptibly is interruptible
     */
    public void testWriteLockInterruptibly_Interrupted() {
	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	Thread t = new Thread(new Runnable() {
                public void run() {
                    try {
			lock.writeLock().lockInterruptibly();
                        lock.writeLock().unlock();
			lock.writeLock().lockInterruptibly();
                        lock.writeLock().unlock();
		    } catch(InterruptedException success){}
		}
	    });
        try {
            lock.writeLock().lock();
            t.start();
            t.interrupt();
            lock.writeLock().unlock();
            t.join();
        } catch(Exception e){
            unexpectedException();
        }
    }

    /**
     * timed write-tryLock is interruptible
     */
    public void testWriteTryLock_Interrupted() {
	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	lock.writeLock().lock();
	Thread t = new Thread(new Runnable() {
                public void run() {
                    try {
			lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
		    } catch(InterruptedException success){}
		}
	    });
        try {
            t.start();
            t.interrupt();
            lock.writeLock().unlock();
            t.join();
        } catch(Exception e){
            unexpectedException();
        }
    }

    /**
     * read-lockInterruptibly is interruptible
     */
    public void testReadLockInterruptibly_Interrupted() {
	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	lock.writeLock().lock();
	Thread t = new Thread(new Runnable() {
                public void run() {
                    try {
			lock.readLock().lockInterruptibly();
		    } catch(InterruptedException success){}
		}
	    });
        try {
            t.start();
            t.interrupt();
            lock.writeLock().unlock();
            t.join();
        } catch(Exception e){
            unexpectedException();
        }
    }

    /**
     * timed read-tryLock is interruptible
     */
    public void testReadTryLock_Interrupted() {
	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	lock.writeLock().lock();
	Thread t = new Thread(new Runnable() {
                public void run() {
                    try {
			lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS);
			threadShouldThrow();
		    } catch(InterruptedException success){}
		}
	    });
        try {
            t.start();
            t.interrupt();
            t.join();
        } catch(Exception e){
            unexpectedException();
        }
    }


    /**
     * write-tryLock fails if locked
     */
    public void testWriteTryLockWhenLocked() {
	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	lock.writeLock().lock();
	Thread t = new Thread(new Runnable() {
                public void run() {
                    threadAssertFalse(lock.writeLock().tryLock());
		}
	    });
        try {
            t.start();
            t.join();
            lock.writeLock().unlock();
        } catch(Exception e){
            unexpectedException();
        }
    }

    /**
     * read-tryLock fails if locked
     */
    public void testReadTryLockWhenLocked() {
	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	lock.writeLock().lock();
	Thread t = new Thread(new Runnable() {
                public void run() {
                    threadAssertFalse(lock.readLock().tryLock());
		}
	    });
        try {
            t.start();
            t.join();
            lock.writeLock().unlock();
        } catch(Exception e){
            unexpectedException();
        }
    }

    /**
     * Multiple threads can hold a read lock when not write-locked
     */
    public void testMultipleReadLocks() {
	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	lock.readLock().lock();
	Thread t = new Thread(new Runnable() {
                public void run() {
                    threadAssertTrue(lock.readLock().tryLock());
                    lock.readLock().unlock();
		}
	    });
        try {
            t.start();
            t.join();
            lock.readLock().unlock();
        } catch(Exception e){
            unexpectedException();
        }
    }

    /**
     * A writelock succeeds after reading threads unlock
     */
    public void testWriteAfterMultipleReadLocks() {
	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	lock.readLock().lock();
	Thread t1 = new Thread(new Runnable() {
                public void run() {
                    lock.readLock().lock();
                    lock.readLock().unlock();
		}
	    });
	Thread t2 = new Thread(new Runnable() {
                public void run() {
                    lock.writeLock().lock();
                    lock.writeLock().unlock();
		}
	    });

        try {
            t1.start();
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            lock.readLock().unlock();
            t1.join(MEDIUM_DELAY_MS);
            t2.join(MEDIUM_DELAY_MS);
            assertTrue(!t1.isAlive());
            assertTrue(!t2.isAlive());

        } catch(Exception e){
            unexpectedException();
        }
    }

    /**
     * Readlocks succeed after a writing thread unlocks
     */
    public void testReadAfterWriteLock() {
	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	lock.writeLock().lock();
	Thread t1 = new Thread(new Runnable() {
                public void run() {
                    lock.readLock().lock();
                    lock.readLock().unlock();
		}
	    });
	Thread t2 = new Thread(new Runnable() {
                public void run() {
                    lock.readLock().lock();
                    lock.readLock().unlock();
		}
	    });

        try {
            t1.start();
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            lock.writeLock().unlock();
            t1.join(MEDIUM_DELAY_MS);
            t2.join(MEDIUM_DELAY_MS);
            assertTrue(!t1.isAlive());
            assertTrue(!t2.isAlive());

        } catch(Exception e){
            unexpectedException();
        }
    }

    /**
     * Read trylock succeeds if write locked by current thread
     */
    public void testReadHoldingWriteLock() {
	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	lock.writeLock().lock();
        assertTrue(lock.readLock().tryLock());
        lock.readLock().unlock();
        lock.writeLock().unlock();
    }

    /**
     * Read lock succeeds if write locked by current thread even if
     * other threads are waiting
     */
    public void testReadHoldingWriteLock2() {
	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	lock.writeLock().lock();
	Thread t1 = new Thread(new Runnable() {
                public void run() {
                    lock.readLock().lock();
                    lock.readLock().unlock();
		}
	    });
	Thread t2 = new Thread(new Runnable() {
                public void run() {
                    lock.readLock().lock();
                    lock.readLock().unlock();
		}
	    });

        try {
            t1.start();
            t2.start();
            lock.readLock().lock();
            lock.readLock().unlock();
            Thread.sleep(SHORT_DELAY_MS);
            lock.readLock().lock();
            lock.readLock().unlock();
            lock.writeLock().unlock();
            t1.join(MEDIUM_DELAY_MS);
            t2.join(MEDIUM_DELAY_MS);
            assertTrue(!t1.isAlive());
            assertTrue(!t2.isAlive());

        } catch(Exception e){
            unexpectedException();
        }
    }

//    /**
//     * Fair Read trylock succeeds if write locked by current thread
//     */
//    public void testReadHoldingWriteLockFair() {
//	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
//	lock.writeLock().lock();
//        assertTrue(lock.readLock().tryLock());
//        lock.readLock().unlock();
//        lock.writeLock().unlock();
//    }

//    /**
//     * Fair Read lock succeeds if write locked by current thread even if
//     * other threads are waiting
//     */
//    public void testReadHoldingWriteLockFair2() {
//	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
//	lock.writeLock().lock();
//	Thread t1 = new Thread(new Runnable() {
//                public void run() {
//                    lock.readLock().lock();
//                    lock.readLock().unlock();
//		}
//	    });
//	Thread t2 = new Thread(new Runnable() {
//                public void run() {
//                    lock.readLock().lock();
//                    lock.readLock().unlock();
//		}
//	    });
//
//        try {
//            t1.start();
//            t2.start();
//            lock.readLock().lock();
//            lock.readLock().unlock();
//            Thread.sleep(SHORT_DELAY_MS);
//            lock.readLock().lock();
//            lock.readLock().unlock();
//            lock.writeLock().unlock();
//            t1.join(MEDIUM_DELAY_MS);
//            t2.join(MEDIUM_DELAY_MS);
//            assertTrue(!t1.isAlive());
//            assertTrue(!t2.isAlive());
//
//        } catch(Exception e){

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?