| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| /* |
| * Entry point and tests that are expected to succeed. |
| */ |
| public class Main { |
| /** |
| * Drives tests. |
| */ |
| public static void main(String[] args) { |
| Main m = new Main(); |
| |
| m.recursiveSync(0); |
| |
| m.nestedMayThrow(false); |
| try { |
| m.nestedMayThrow(true); |
| System.err.println("nestedThrow(true) did not throw"); |
| } catch (MyException me) {} |
| System.out.println("nestedMayThrow ok"); |
| |
| m.constantLock(); |
| System.out.println("constantLock ok"); |
| |
| m.notExcessiveNesting(); |
| try { |
| TooDeep.excessiveNesting(); |
| System.err.println("excessiveNesting did not throw"); |
| } catch (VerifyError ve) {} |
| System.out.println("excessiveNesting ok"); |
| |
| m.notNested(); |
| System.out.println("notNested ok"); |
| |
| Object obj1 = new Object(); |
| Object obj2 = new Object(); |
| |
| m.twoPath(obj1, obj2, 0); |
| System.out.println("twoPath ok"); |
| |
| m.triplet(obj1, obj2, 0); |
| System.out.println("triplet ok"); |
| } |
| |
| /** |
| * Recursive synchronized method. |
| */ |
| synchronized void recursiveSync(int iter) { |
| if (iter < 40) { |
| recursiveSync(iter+1); |
| } else { |
| System.out.println("recursiveSync ok"); |
| } |
| } |
| |
| /** |
| * Tests simple nesting, with and without a throw. |
| */ |
| void nestedMayThrow(boolean doThrow) { |
| synchronized (this) { |
| synchronized (Main.class) { |
| synchronized (new Object()) { |
| synchronized(Class.class) { |
| if (doThrow) { |
| throw new MyException(); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Exercises bug 3215458. |
| */ |
| void constantLock() { |
| Class thing = Thread.class; |
| synchronized (Thread.class) {} |
| } |
| |
| /** |
| * Confirms that we can have 32 nested monitors on one method. |
| */ |
| void notExcessiveNesting() { |
| synchronized (this) { // 1 |
| synchronized (this) { // 2 |
| synchronized (this) { // 3 |
| synchronized (this) { // 4 |
| synchronized (this) { // 5 |
| synchronized (this) { // 6 |
| synchronized (this) { // 7 |
| synchronized (this) { // 8 |
| synchronized (this) { // 9 |
| synchronized (this) { // 10 |
| synchronized (this) { // 11 |
| synchronized (this) { // 12 |
| synchronized (this) { // 13 |
| synchronized (this) { // 14 |
| synchronized (this) { // 15 |
| synchronized (this) { // 16 |
| synchronized (this) { // 17 |
| synchronized (this) { // 18 |
| synchronized (this) { // 19 |
| synchronized (this) { // 20 |
| synchronized (this) { // 21 |
| synchronized (this) { // 22 |
| synchronized (this) { // 23 |
| synchronized (this) { // 24 |
| synchronized (this) { // 25 |
| synchronized (this) { // 26 |
| synchronized (this) { // 27 |
| synchronized (this) { // 28 |
| synchronized (this) { // 29 |
| synchronized (this) { // 30 |
| synchronized (this) { // 31 |
| synchronized (this) { // 32 |
| }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} |
| } |
| |
| /** |
| * Confirms that we can have more than 32 non-nested monitors in one |
| * method. |
| */ |
| void notNested() { |
| synchronized (this) {} // 1 |
| synchronized (this) {} // 2 |
| synchronized (this) {} // 3 |
| synchronized (this) {} // 4 |
| synchronized (this) {} // 5 |
| synchronized (this) {} // 6 |
| synchronized (this) {} // 7 |
| synchronized (this) {} // 8 |
| synchronized (this) {} // 9 |
| synchronized (this) {} // 10 |
| synchronized (this) {} // 11 |
| synchronized (this) {} // 12 |
| synchronized (this) {} // 13 |
| synchronized (this) {} // 14 |
| synchronized (this) {} // 15 |
| synchronized (this) {} // 16 |
| synchronized (this) {} // 17 |
| synchronized (this) {} // 18 |
| synchronized (this) {} // 19 |
| synchronized (this) {} // 20 |
| synchronized (this) {} // 21 |
| synchronized (this) {} // 22 |
| synchronized (this) {} // 23 |
| synchronized (this) {} // 24 |
| synchronized (this) {} // 25 |
| synchronized (this) {} // 26 |
| synchronized (this) {} // 27 |
| synchronized (this) {} // 28 |
| synchronized (this) {} // 29 |
| synchronized (this) {} // 30 |
| synchronized (this) {} // 31 |
| synchronized (this) {} // 32 |
| synchronized (this) {} // 33 |
| synchronized (this) {} // 34 |
| } |
| |
| /* does nothing but ensure that the compiler doesn't discard an object */ |
| private void doNothing(Object obj) {} |
| |
| /** |
| * Conditionally uses one of the synchronized objects. |
| */ |
| public void twoPath(Object obj1, Object obj2, int x) { |
| Object localObj; |
| |
| synchronized (obj1) { |
| synchronized(obj2) { |
| if (x == 0) { |
| localObj = obj2; |
| } else { |
| localObj = obj1; |
| } |
| } |
| } |
| |
| doNothing(localObj); |
| } |
| |
| /** |
| * Lock the monitor two or three times, and make use of the locked or |
| * unlocked object. |
| */ |
| public void triplet(Object obj1, Object obj2, int x) { |
| Object localObj; |
| |
| synchronized (obj1) { |
| synchronized(obj1) { |
| if (x == 0) { |
| synchronized(obj1) { |
| localObj = obj2; |
| } |
| } else { |
| localObj = obj1; |
| } |
| } |
| } |
| |
| doNothing(localObj); |
| } |
| } |