On Windows (I used the MinGW version 3.3.1 of gcj), there's a bug if a synchronized method calls wait(). If the method containing wait() was invoked by another synchronized method of the same object, then the calling thread keeps the lock on this object. Example program: If you run this with the Java 1.4.1 VM on Windows, the output is a c c c ... If compiled with GCJ on Windows, the output is only a Code of the example program: public class Test { public static void main(String args[]) { Test test = new Test(); new MyThread(test).start(); while(true) { try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } test.c(); } } public synchronized void a() { System.out.println("a"); b(); } public synchronized void b() { try { wait(); } catch (Exception e) { e.printStackTrace(); } System.out.println("b"); } public synchronized void c() { System.out.println("c"); } } class MyThread extends Thread { private Test test; public MyThread(Test test) { this.test = test; } public void run() { test.a(); } }
This works for me on powerpc-apple-darwin on the mainline (20031008), I do not have access to a Windows machine to try this.
Mohan, can you confirm this?
Confirmed with CVS HEAD (3.4).
http://gcc.gnu.org/ml/java-patches/2003-q4/msg00224.html
Subject: Bug 12647 CVSROOT: /cvs/gcc Module name: gcc Changes by: membar@gcc.gnu.org 2003-10-31 03:36:38 Modified files: libjava : ChangeLog win32-threads.cc Log message: PR libgcj/12647: * win32-threads.cc (_Jv_CondWait): Respect mutex's refcount when releasing and reacquiring it. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/ChangeLog.diff?cvsroot=gcc&r1=1.2317&r2=1.2318 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/win32-threads.cc.diff?cvsroot=gcc&r1=1.10&r2=1.11
Fixed for 3.4.