Thanks for the replies. I have worked further on this and the particular issue isn't with GC barriers but with M-to-N threading. In theory if 1 of the M threads becomes blocked in a JNI call then the other threads should be moved onto another of the N underlying native threads. Unfortunately, as it's possible to call back into the JVM, the JVM's yield code can schedule another thread on the same native thread before realising the 1st thread is blocked and now its possibly handling a second blocked thread but now on the same native thread. Scheduling blocked 2 native threads running on the same native thread requires a rewrite to the underlying native thread library. For the gtk peers this is done by enabling the portable native sync code, but my experience is that this is currently broken (and using it is not advised as it would inhibit the using JVM from being used as a plugin in a gthreaded application). In any case having a fixed number of N underlying threads will probably also become a problem. Anyway, I have a small proposed change to gdk_threads_enter for JVMs with M-to-N threading (in gtkpeer.h): #define M_TO_N_JAVA_THREADING 1 #if M_TO_N_JAVA_THREADING #define gdk_threads_enter() \ { \ JNIEnv *env = cp_gtk_gdk_env(); \ while(g_mutex_trylock(gdk_threads_mutex) == FALSE){ \ jclass thread_class = (*env)->FindClass (env, "java/lang/Thread"); \ jmethodID thread_yield_mth = (*env)->GetStaticMethodID (env, thread_class, "yield", "()V"); \ (*env)->CallStaticVoidMethod (env, thread_class, thread_yield_mth); \ } \ g_mutex_unlock(gdk_threads_mutex); \ gdk_threads_enter(); \ } #endif it prevents 2 java threads on the same native thread becoming deadlocked on the gdk_threads_mutex. Unfortunately the gdk_threads_mutex is supposed to be private, but I think accessing it here is suitable. I think removing the portable native sync code and having specific fixes for M-to-N threading is an appropriate change. What are others opinions? As part of this would it be possible to have versions of JNI routines that don't return that at least call Java yield in the case of being on a M-to-N threaded JVM? Thanks, Ian Rogers