1 /* 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 @test 26 @summary Some tests for the Lock spec 27 @summary com.apple.junit.java.lang.LanguageSpec; 28 @run main LockTest 29 */ 30 31 import junit.framework.*; 32 33 import java.util.Timer; 34 import java.util.TimerTask; 35 36 //Lock class representation of Lock, with flag to indicate whether locked or not, and with 37 //count of number of times lock acquired. 38 class Lock { 39 static int numLocks = 0; 40 static boolean isLocked = false; 41 42 //Acquires lock and increments numLock 43 public static synchronized void acquire() throws Exception { 44 if ( numLocks < 0) { 45 throw new Exception("Locking logic error"); 46 } 47 numLocks++; 48 isLocked = true; 49 } 50 51 //Releases current lock, if all locks released, Lock is unlocked 52 public static synchronized void release() throws Exception { 53 if ( numLocks < 1) { 54 throw new Exception("Locking logic error"); 55 } 56 numLocks--; 57 58 if(numLocks == 0) 59 isLocked = false; 60 } 61 } 62 63 64 public class LockTest extends TestCase { 65 Thread t1; 66 Thread t2; 67 Lock l1; 68 TimerTask stopper; 69 static volatile boolean done; 70 Timer timer; 71 72 class Stopper extends TimerTask{ 73 public void run(){ 74 done = true; 75 } 76 } 77 78 //Sets up new threads t1 and t2. 79 public void setUp(){ 80 l1 = new Lock(); 81 done = false; 82 } 83 84 85 //Create two threads. One uses synchronized to aqcuire multiple locks on the instance l1 of Lock 86 //The other thread attempts to acquire a lock on l1 while it is already locked by the first thread 87 //If the second thread manages to acquire a lock on l1 while already locked by the first thread, 88 //the test fails. Also tests number of locks acquired. 89 //Tests JVM spec as specified in 8.5 and 8.6 90 91 Exception cachedException; 92 93 public void testLock() throws Exception { 94 timer = new Timer(); 95 t1 = new Thread( new Runnable() { 96 public void run() { 97 try{ 98 while (!done) { 99 synchronized(l1) { 100 assertFalse(Lock.isLocked); 101 Lock.acquire(); 102 assertEquals(Lock.numLocks, 1); 103 Thread.sleep(10); 104 synchronized(l1) { 105 Lock.acquire(); 106 assertEquals(Lock.numLocks, 2); 107 Thread.sleep(10); 108 synchronized(l1) { 109 Lock.acquire(); 110 assertEquals(Lock.numLocks, 3); 111 Thread.sleep(10); 112 Lock.release(); 113 assertEquals(Lock.numLocks, 2); 114 } 115 Thread.sleep(10); 116 Lock.release(); 117 assertEquals(Lock.numLocks, 1); 118 } 119 Thread.sleep(10); 120 Lock.release(); 121 assertEquals(Lock.numLocks, 0); 122 } 123 } 124 } catch (Exception e) { 125 cachedException = e; 126 } 127 } 128 }); 129 130 t2 = new Thread ( new Runnable() { 131 public void run() { 132 try { 133 while(!done) { 134 synchronized(l1){ 135 assertFalse(Lock.isLocked); 136 Lock.acquire(); 137 assertEquals(Lock.numLocks, 1); 138 Lock.release(); 139 assertEquals(Lock.numLocks, 0); 140 } 141 } 142 } catch (Exception e) { 143 cachedException = e; 144 } 145 } 146 }); 147 148 try { 149 timer.schedule(new Stopper(), 500); 150 t1.start(); 151 t2.start(); 152 t1.join(); 153 t2.join(); 154 155 if (cachedException != null) { 156 throw cachedException; 157 } 158 } 159 160 finally { 161 timer.cancel(); 162 } 163 164 } 165 166 public static Test suite() { 167 return new TestSuite( LockTest.class); 168 } 169 170 public static void main (String[] args) throws RuntimeException { 171 TestResult tr = junit.textui.TestRunner.run(suite()); 172 if((tr.errorCount() != 0) || (tr.failureCount() != 0)) { 173 throw new RuntimeException("### Unexpected JUnit errors or failures."); 174 } 175 } 176 } 177