/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4530538
* @summary Basic unit test of ThreadInfo.getBlockedCount()
* @author Alexei Guibadoulline and Mandy Chung
*
* @build ThreadExecutionSynchronizer
* @run main ThreadBlockedCount
*/
public class ThreadBlockedCount {
private static boolean aNotified = false;
private static boolean bNotified = false;
private static boolean cNotified = false;
private static volatile boolean testFailed = false;
// Create the BlockingThread before BlockedThread
// to make sure BlockingThread enter the lock before BlockedThread
thrsync = new ThreadExecutionSynchronizer();
blocking = new BlockingThread();
blocked = new BlockedThread();
try {
} catch (InterruptedException e) {
throw e;
}
if (testFailed) {
throw new RuntimeException("TEST FAILED.");
}
}
// NOTE: We can't use a.wait() here because wait() call is counted
// as blockedCount. Instead, we use a boolean flag and sleep.
//
public void run() {
// wait Blocking thread
// Enter lock a without blocking
synchronized (a) {
// wait until BlockingThread holds blockedObj1
while (!aNotified) {
try {
} catch (InterruptedException e) {
testFailed = true;
}
}
// signal BlockingThread.
// Block to enter blockedObj1
// blockedObj1 should be owned by BlockingThread
synchronized (blockedObj1) {
}
}
// signal BlockingThread.
// Enter lock a without blocking
synchronized (b) {
// wait until BlockingThread holds blockedObj2
while (!bNotified) {
try {
} catch (InterruptedException e) {
testFailed = true;
}
}
// signal BlockingThread.
// Block to enter blockedObj2
// blockedObj2 should be owned by BlockingThread
synchronized (blockedObj2) {
}
}
// signal BlockingThread.
// Enter lock a without blocking
synchronized (c) {
// wait until BlockingThread holds blockedObj3
while (!cNotified) {
try {
} catch (InterruptedException e) {
testFailed = true;
}
}
// signal BlockingThread.
// Block to enter blockedObj3
// blockedObj3 should be owned by BlockingThread
synchronized (blockedObj3) {
}
}
// Check the mbean now
getId());
if (count != EXPECTED_BLOCKED_COUNT) {
" blocked counts. Expected " +
testFailed = true;
}
} // run()
} // BlockingThread
private void waitForSignalToRelease() {
// wait for BlockedThread.
boolean threadBlocked = false;
while (!threadBlocked) {
// give a chance for BlockedThread to really block
try {
} catch (InterruptedException e) {
testFailed = true;
}
}
}
public void run() {
// wait for BlockedThread.
synchronized (blockedObj1) {
aNotified = true;
}
// wait for BlockedThread.
// block until BlockedThread is ready
synchronized (blockedObj2) {
bNotified = true;
}
// wait for BlockedThread.
// block until BlockedThread is ready
synchronized (blockedObj3) {
cNotified = true;
}
} // run()
} // BlockedThread
}