changeset 57717:93559c88be23

8236873: Worker has a deadlock bug Reviewed-by: dfuchs, dholmes, sspitsyn
author dtitov
date Thu, 16 Jan 2020 09:53:03 -0800
parents 3edb7d802ccb
children 09371a74ca50
files src/jdk.jconsole/share/classes/sun/tools/jconsole/Worker.java test/jdk/sun/tools/jconsole/WorkerDeadlockTest.java
diffstat 2 files changed, 55 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.jconsole/share/classes/sun/tools/jconsole/Worker.java	Thu Jan 16 13:48:23 2020 +0000
+++ b/src/jdk.jconsole/share/classes/sun/tools/jconsole/Worker.java	Thu Jan 16 09:53:03 2020 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2020 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
 
 public class Worker extends Thread {
     ArrayList<Runnable> jobs = new ArrayList<Runnable>();
-    private boolean stopped = false;
+    private volatile boolean stopped = false;
 
     public Worker(String name) {
         super("Worker-"+name);
@@ -38,17 +38,17 @@
     }
 
     public void run() {
-        while (!isStopped()) {
+        while (!stopped) {
             Runnable job;
             synchronized(jobs) {
-                while (!isStopped() && jobs.size() == 0) {
+                while (!stopped && jobs.size() == 0) {
                     try {
                         jobs.wait();
                     } catch (InterruptedException ex) {
                     }
                 }
 
-                if(isStopped()) break;
+                if(stopped) break;
 
                 job = jobs.remove(0);
             }
@@ -56,11 +56,7 @@
         }
     }
 
-    private synchronized boolean isStopped() {
-        return stopped;
-    }
-
-    public synchronized void stopWorker() {
+    public void stopWorker() {
         stopped = true;
         synchronized(jobs) {
             jobs.notify();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/tools/jconsole/WorkerDeadlockTest.java	Thu Jan 16 09:53:03 2020 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8236872
+ * @summary The test tries to catch a deadlock by creating a new worker,
+ * starting it, adding an empty job and immediately stopping it.
+ * @modules jdk.jconsole/sun.tools.jconsole
+ * @run main WorkerDeadlockTest
+ */
+
+import sun.tools.jconsole.Worker;
+
+
+public class WorkerDeadlockTest {
+    private static final int REPEAT_NUMBER = 1000;
+
+    public static void main(String[] args) {
+
+        for (int i = 1; i < REPEAT_NUMBER; i++) {
+            Worker worker = new Worker("worker-" + i);
+            worker.start();
+            worker.add(() -> { });
+            worker.stopWorker();
+            System.out.println("Worker " + i + " was successfully stopped");
+        }
+    }
+}