OversynchronizedTest.java revision 2362
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams/*
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams *
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams * This code is free software; you can redistribute it and/or modify it
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams * under the terms of the GNU General Public License version 2 only, as
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams * published by the Free Software Foundation.
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams *
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams * This code is distributed in the hope that it will be useful, but WITHOUT
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3437829f938dbb44527d91fbbc5f430a1243c5a5JnRouvignac * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3437829f938dbb44527d91fbbc5f430a1243c5a5JnRouvignac * version 2 for more details (a copy is included in the LICENSE file that
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams * accompanied this code).
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams *
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams * You should have received a copy of the GNU General Public License version
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams * 2 along with this work; if not, write to the Free Software Foundation,
3437829f938dbb44527d91fbbc5f430a1243c5a5JnRouvignac * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
3437829f938dbb44527d91fbbc5f430a1243c5a5JnRouvignac *
3437829f938dbb44527d91fbbc5f430a1243c5a5JnRouvignac * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
3437829f938dbb44527d91fbbc5f430a1243c5a5JnRouvignac * or visit www.oracle.com if you need additional information or have any
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams * questions.
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams */
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams/* @test
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams @bug 4905777
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams @summary PrintWriter.println(Object) oversynchronized, can deadlock
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams*/
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williamsimport java.io.PrintWriter;
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williamspublic class OversynchronizedTest extends Thread {
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams private static PrintWriter writer = new PrintWriter(System.out);
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams private static TestObj testObj = new TestObj("This is a test.", writer);
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams private static int loopNum = 100;
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams public void run() {
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams for(int i=0; i<loopNum; i++) {
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams testObj.test();
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams //passing an object to PrintWriter.println might cause deadlock
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams //if the object has a synchronized toString() method.
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams //using PrintWriter.println(testObj.toString()) won't have a problem
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams writer.println(testObj);
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams }
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams }
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams public static void main(String args[]) throws Exception {
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams // should no NullPointerException
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams writer.println((Object)null);
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams int num = 5;
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams OversynchronizedTest[] t = new OversynchronizedTest[num];
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams for(int i=0; i<num; i++) {
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams t[i] = new OversynchronizedTest();
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams t[i].start();
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams }
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams for(int i=0; i <num; i++) {
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams t[i].join();
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams }
6ebf517304e8113daef6fa04a6278fe50ebd6aaegary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams System.out.println("Test completed");
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams }
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams}
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williamsclass TestObj {
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams String mStr;
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams TestObj(String str, PrintWriter writer) {
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams mStr = str;
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams this.writer = writer;
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams }
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams synchronized void test() {
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams try {
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams long t = Math.round(Math.random()*10);
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams Thread.currentThread().sleep(t);
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams } catch (InterruptedException e) {
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams // jtreg timeout?
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams // Only jtreg will interrupt this thread so it knows what to do:
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams e.printStackTrace();
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams }
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams //the following line might cause hang if there is PrintWriter.println(testObj)
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams //called by other threads.
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams writer.println("In test().");
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams }
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams synchronized public String toString() {
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams writer.println("Calling toString\n");
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams return mStr;
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams }
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams private PrintWriter writer;
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams}
9fce8bf90e08efa065faf5ebf13a8ce4ea48f0e6gary.williams