01: /**
02: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
03: */package com.tc.util.concurrent;
04:
05: import java.lang.reflect.Field;
06:
07: import sun.misc.Unsafe;
08:
09: public class MonitorUtils {
10:
11: private static final Unsafe unsafe;
12:
13: static {
14: try {
15: Class unsafeClass = Class.forName("sun.misc.Unsafe");
16: Field getter = unsafeClass.getDeclaredField("theUnsafe");
17: getter.setAccessible(true);
18: unsafe = (Unsafe) getter.get(null);
19: } catch (Throwable t) {
20: t.printStackTrace();
21: throw new RuntimeException(
22: "Unable to access sun.misc.Unsafe");
23: }
24: }
25:
26: private MonitorUtils() {
27: // utility class -- not for instantiation
28: }
29:
30: public static void monitorEnter(Object object) {
31: unsafe.monitorEnter(object);
32: }
33:
34: public static void monitorExit(Object object) {
35: unsafe.monitorExit(object);
36: }
37:
38: public static void monitorEnter(Object object, int count) {
39: for (int i = 0; i < count; i++) {
40: unsafe.monitorEnter(object);
41: }
42: }
43:
44: /**
45: * Completely release the monitor on the given object (calling thread needs to own the monitor obviously)
46: *
47: * @return the number of monitorExit calls performed
48: */
49: public static int releaseMonitor(Object object) {
50: if (object == null) {
51: throw new NullPointerException("object is null");
52: }
53: if (!Thread.holdsLock(object)) {
54: throw new IllegalMonitorStateException("not monitor owner");
55: }
56:
57: // This has the side effect of inflating the monitor (see VM source). It may not be necessary on all platforms (and
58: // can be optimized as such if necessary).
59: unsafe.monitorEnter(object);
60: unsafe.monitorExit(object);
61:
62: int count = 0;
63: while (Thread.holdsLock(object)) {
64: unsafe.monitorExit(object);
65: count++;
66: }
67:
68: return count++;
69: }
70: }
|