Thread isolation in Java
Asked Answered
A

7

5

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!

Aponeurosis answered 17/8, 2009 at 14:11 Comment(0)
T
11

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 elaborate, 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 Java EE Application Servers. That in turn leads to questions of which classloader and classpath gets used when the libraries themselves start to do some reflection and dynamic classloading. I would not recommend this approach 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 overhead try to find a thread-safe alternative to the libraries, 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.

Tajuanatak answered 17/8, 2009 at 14:15 Comment(0)
B
4

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.

Brumbaugh answered 17/8, 2009 at 14:20 Comment(0)
P
3

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 .

Psych answered 17/8, 2009 at 22:41 Comment(0)
F
0

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?

Flavorful answered 17/8, 2009 at 14:15 Comment(0)
V
0

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.

Valma answered 17/8, 2009 at 14:19 Comment(0)
F
0

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

Foliole answered 17/8, 2009 at 14:22 Comment(0)
K
0

You can try putting the resources in a single executor, in such way that you will never have two of those processes running in parallel.

The way you can do it is by means of Executors:

class Foo {
  private ExecutorService executor = Executors.newSingleThreadExecutor();

  public void addTask(Runnable bar) {
    executor.submit(bar);
  }
}
Kolb answered 17/8, 2009 at 15:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.