views:

280

answers:

7

Is there any sure-fire way to ensure Threads remain isolated from one-another, in Java? I've had an issue for a week and a half, where Threads implementing various 3rd party source code keep colliding due to static variables and other such things that are really beyond my control.

I know a single system can run as many instances of the project I'm working on, as it wants. But when trying to incorporate everything into a threaded, single executable, there are always errors and exceptions.

I'm almost at the point of just launching a new Process for each instance of this program that I want, but I'd really rather not go down this route (it would eliminate a lot of real-time data I gather, as well as hinder my ability to kill a targeted process.)

Suggestions? Thanks!

+9  A: 

If the authors of the library you want to use have not designed their code to be thread safe, then there's little you can easily do except to prevent two of your threads calling it at the same time.

You can pull some tricks with classloaders, but this tends to lead to a whole new world of complexity. To elaorate, it's possible to load the same class twice (or more times) into the same JVM, if you use different classloaders - hence you could effectively get independent copies of static variables. This use of separate classloaders is exploited by some JEE Application Servers. That in turn leads to questions of which classloader and classpath gets used when the libraries themselves start to do some reflecion and dynamic classloading. I would not recommend this appraoch unless your need is very great.

By preferences would be :

1). Have a single-threaded worker for the unsafe code. Try to do as much work as possible out in your mulit-threaded app, dropping into the Worker as little as you can.

2). If the worker is the major part of your processing and so you really need parallel execution pull the worker out into mulitple separate processes, use some IPC communication to share the work out. This feels like a JMS queueing solution might work nicely.

3). If you can't afford the IPC overhea try to find a thread-safe alternative to the libaries, or if you have influence with the authors get them to fix the code. It really should not be that hard to increase their parallelism.

djna
A: 

There is no way to do this, unfortunately. If threads access shared resources they should lock these resources as required, otherwise your program will definitely face corruption of the shared state.

Maybe you can wrap access to the shared resources in a way that allows you to synchronize access?

Ronald Wildenberg
A: 

I'm almost at the point of just launching a new Process for each instance of this program that I want, but I'd really rather not go down this route (it would eliminate a lot of real-time data I gather, as well as hinder my ability to kill a targeted process.)

By the sounds of it, the code you are trying to reuse is really not designed to be used in a multi-threaded application. In this case, launching a separate Process for each instance might actually be your best option. Rather than hindering your ability to kill each instance, it should actually make this easier to do; see Process.destroy().

While it is not clear what you mean by "real-time", if each child process writes to its standard output, you can code your control program to read and collate the output as it is written.

Stephen C
+3  A: 

Threads implementing various 3rd party source code keep colliding due to static variables and other such things that are really beyond my control.

If that's really the case then I think you have to go down that road of having separate processes. If the code you call is not thread-safe then all you can do is to make sure that this code is only called by one process at a time. Which basically eliminates the advantages of running it in a different thread.

as well as hinder my ability to kill a targeted process

I don't see your point here. Only with processes you can safely kill the processing, it is not possible to do this in a safe way with threads if you don't have complete control over all the code that is run.

See also this question for a discussion of a similar problem.

Robert Petermeier
A: 

You could use a separate class loader for each thread, to load the third-party libraries you want to keep separate.

starblue
A: 
Oso
+1  A: 

Your requirement is covered by JSR-121, which was approved in 2006.

I didn't hear much about implementations of JSR-121, but a quick search led me to http://weblogs.java.net/blog/gczaj/archive/j2se/index.html .

Marian