1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 18 /* 19 * Entry point and tests that are expected to succeed. 20 */ 21 public class Main { 22 /** 23 * Drives tests. 24 */ 25 public static void main(String[] args) { 26 Main m = new Main(); 27 28 m.recursiveSync(0); 29 30 m.nestedMayThrow(false); 31 try { 32 m.nestedMayThrow(true); 33 System.err.println("nestedThrow(true) did not throw"); 34 } catch (MyException me) {} 35 System.out.println("nestedMayThrow ok"); 36 37 m.constantLock(); 38 System.out.println("constantLock ok"); 39 40 m.notExcessiveNesting(); 41 try { 42 TooDeep.excessiveNesting(); 43 System.err.println("excessiveNesting did not throw"); 44 } catch (VerifyError ve) {} 45 System.out.println("excessiveNesting ok"); 46 47 m.notNested(); 48 System.out.println("notNested ok"); 49 50 Object obj1 = new Object(); 51 Object obj2 = new Object(); 52 53 m.twoPath(obj1, obj2, 0); 54 System.out.println("twoPath ok"); 55 56 m.triplet(obj1, obj2, 0); 57 System.out.println("triplet ok"); 58 } 59 60 /** 61 * Recursive synchronized method. 62 */ 63 synchronized void recursiveSync(int iter) { 64 if (iter < 40) { 65 recursiveSync(iter+1); 66 } else { 67 System.out.println("recursiveSync ok"); 68 } 69 } 70 71 /** 72 * Tests simple nesting, with and without a throw. 73 */ 74 void nestedMayThrow(boolean doThrow) { 75 synchronized (this) { 76 synchronized (Main.class) { 77 synchronized (new Object()) { 78 synchronized(Class.class) { 79 if (doThrow) { 80 throw new MyException(); 81 } 82 } 83 } 84 } 85 } 86 } 87 88 /** 89 * Exercises bug 3215458. 90 */ 91 void constantLock() { 92 Class thing = Thread.class; 93 synchronized (Thread.class) {} 94 } 95 96 /** 97 * Confirms that we can have 32 nested monitors on one method. 98 */ 99 void notExcessiveNesting() { 100 synchronized (this) { // 1 101 synchronized (this) { // 2 102 synchronized (this) { // 3 103 synchronized (this) { // 4 104 synchronized (this) { // 5 105 synchronized (this) { // 6 106 synchronized (this) { // 7 107 synchronized (this) { // 8 108 synchronized (this) { // 9 109 synchronized (this) { // 10 110 synchronized (this) { // 11 111 synchronized (this) { // 12 112 synchronized (this) { // 13 113 synchronized (this) { // 14 114 synchronized (this) { // 15 115 synchronized (this) { // 16 116 synchronized (this) { // 17 117 synchronized (this) { // 18 118 synchronized (this) { // 19 119 synchronized (this) { // 20 120 synchronized (this) { // 21 121 synchronized (this) { // 22 122 synchronized (this) { // 23 123 synchronized (this) { // 24 124 synchronized (this) { // 25 125 synchronized (this) { // 26 126 synchronized (this) { // 27 127 synchronized (this) { // 28 128 synchronized (this) { // 29 129 synchronized (this) { // 30 130 synchronized (this) { // 31 131 synchronized (this) { // 32 132 }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} 133 } 134 135 /** 136 * Confirms that we can have more than 32 non-nested monitors in one 137 * method. 138 */ 139 void notNested() { 140 synchronized (this) {} // 1 141 synchronized (this) {} // 2 142 synchronized (this) {} // 3 143 synchronized (this) {} // 4 144 synchronized (this) {} // 5 145 synchronized (this) {} // 6 146 synchronized (this) {} // 7 147 synchronized (this) {} // 8 148 synchronized (this) {} // 9 149 synchronized (this) {} // 10 150 synchronized (this) {} // 11 151 synchronized (this) {} // 12 152 synchronized (this) {} // 13 153 synchronized (this) {} // 14 154 synchronized (this) {} // 15 155 synchronized (this) {} // 16 156 synchronized (this) {} // 17 157 synchronized (this) {} // 18 158 synchronized (this) {} // 19 159 synchronized (this) {} // 20 160 synchronized (this) {} // 21 161 synchronized (this) {} // 22 162 synchronized (this) {} // 23 163 synchronized (this) {} // 24 164 synchronized (this) {} // 25 165 synchronized (this) {} // 26 166 synchronized (this) {} // 27 167 synchronized (this) {} // 28 168 synchronized (this) {} // 29 169 synchronized (this) {} // 30 170 synchronized (this) {} // 31 171 synchronized (this) {} // 32 172 synchronized (this) {} // 33 173 synchronized (this) {} // 34 174 } 175 176 /* does nothing but ensure that the compiler doesn't discard an object */ 177 private void doNothing(Object obj) {} 178 179 /** 180 * Conditionally uses one of the synchronized objects. 181 */ 182 public void twoPath(Object obj1, Object obj2, int x) { 183 Object localObj; 184 185 synchronized (obj1) { 186 synchronized(obj2) { 187 if (x == 0) { 188 localObj = obj2; 189 } else { 190 localObj = obj1; 191 } 192 } 193 } 194 195 doNothing(localObj); 196 } 197 198 /** 199 * Lock the monitor two or three times, and make use of the locked or 200 * unlocked object. 201 */ 202 public void triplet(Object obj1, Object obj2, int x) { 203 Object localObj; 204 205 synchronized (obj1) { 206 synchronized(obj1) { 207 if (x == 0) { 208 synchronized(obj1) { 209 localObj = obj2; 210 } 211 } else { 212 localObj = obj1; 213 } 214 } 215 } 216 217 doNothing(localObj); 218 } 219 } 220