linux-wide semaphore with a Java API - java

I need to prevent a certain application function from being run concurrently with itself. The risk is significant because this function is in code submitted to java.util.Timer (to repeat every minute for several hours) and the process that sets up the function completes and goes back to the bash command line. The user might then invoke the same program. Another risk is from the user that has two or more console windows and they mistakenly run the program in both console windows.
I think an operating system-wide semaphore with a Java API might do the trick. Is there such a Java archive available?
I was asked if multiple JVMs are used. I think if multiple consoles are opened then multiple JVMs are implied.
This is my wrapper to use Java's Timer and TimerTask.
public final class TimedExecutorWrapper
{ ... various private members ...
public Timer go()
{
Timer myTimer = new Timer();
myTimer.scheduleAtFixedRate(this.myTask,
this.startTodayAtThisTime,
this.frequencyInSeconds * 1000);
TimerTask myTaskToInvokeCancel = new TaskToInvokeCancel(myTimer);
// use the same Timer to schedule the task that cancels and purges
myTimer.schedule(myTaskToInvokeCancel,
this.stopTodayAtThisTime);
return myTimer;
}
private final class TaskToInvokeCancel extends TimerTask
{
private Timer timer; // to be cancelled and purged
TaskToInvokeCancel(Timer timer)
{
this.timer = timer;
}
public void run()
{
this.timer.cancel(); // discards any scheduled tasks without
// interfering with any running task
this.timer.purge();
}
}
}

You could create a 0 byte file 'methodname.LOCK' in a shared directory when you begin the operation, and delete it when you are done. Creating it with a no recreate flag in Java should solve your problem.
Make sure to delete it in a 'finally' block so you are never left in a state where the file exists and continues to block the process from ever running

just open a serversocket at a specific port. if this succeeds there is no other application, if not an exception is thrown.

The only standard Java feature I've seen that prohibits multiple instances of the same program is the SingleInstanceService in Java WebStart.
http://download.oracle.com/javase/1.5.0/docs/guide/javaws/developersguide/examples.html#SingleInstanceService
It requires you to create a JNLP file for your application, which is a bit cumbersome but may be very useful to you anyway. Note that Java does not allow command line parameters to be passed to your program which may be very inconvenient in this situation. Depends on what your command line says.
If Java WebStart does not work for you, then you must ask the operating system for a resource which is denied for subsequent requests and have it automatically released. The only one of these not platform specific is the TCP/IP socket but these are rare and may be used by another program. Under Linux you may ask for shared memory but I do not have personal experience with this.

Related

Forcefully terminating a thread I didn't write in Java

Everywhere I look about how to forcefully stop a thread in Java, I see "just do an exit variable check instead, your program is broken if you need to force kill."
I have a rather unique situation though. I am writing a Java program that dynamically loads and runs other Java classes in a separate thread. (No comments about security risks please, this is a very specific use case).
The trouble is, since other people will have written the classes that need to be loaded, there's no way to guarantee they'll implement the stop checking and whatnot correctly. I need a way to immediately terminate their thread, accepting all the risks involved. Basically I want to kill -9 their thread if I need to. How can I do this in Java?
Update: here's a bit more info:
This is actually an Android app
The user code depends on classes in my application
A user class must be annotated with #UserProgram in order to be "registered" by my application
The user also has the option of building their classes right into the application (by downloading a project with the internal classes already compiled into a libraries and putting their classes in a separate module) rather than having them dynamically loaded from a JAR.
The user classes extend from my template class which has a runUserProgram() method that they override. Inside that method, they are free to do anything they want. They can check isStopRequested() to see if I want them to stop, but I have no guarantee that they'll do that.
On startup, my application loads any JARs specified and scans both all the classes in the application and the classes in those JARs to find any classes annotated with the aforementioned annotation. Once a list of those classes is built, it is fed into the frontend where the UI provides a list of programs that can be run. Once a program is selected, a "start" button must be pressed to actually start it. When it is pressed, the button changes to a "stop" button and a callback is fired into the backend to load up the selected class in a new thread and call the runUserProgram() method. When the "stop" button is pressed, a variable is set which causes isStopRequested() to return true.
You can kill -9 it by running in its own process i.e. start with a ProcessBuilder and call Process.destroyForcibly() to kill it.
ProcessBuilder pb = new ProcessBuilder("java", "-cp", "myjar.jar");
pb.redirectErrorStream();
Process process = pb.start();
// do something with the program.
Scanner sc = new Scanner(process.getOutputStream());
while (sc.hasNextLine()) {
System.out.println(sc.nextLine());
}
// when done, possibly in another thread so it doesn't get blocked by reading.
process.waitFor(1, TimeUnit.SECONDS);
if (process.isAlive())
process.destroyForcibly();
Java 8 had Thread.stop(). The problem is that it could only work reasonably for very limited use cases, so limited you were better off using interrupts, and if the code isn't trusted, neither are any good.
There is the deprecated Thread.stop() but don't use it.
There is no way to cleanly terminate another thread without it cooperating.
The thread can be in a state where it allocated some memory, or added some objects to some global state, locked some mutexes, etc. If you kill it at the wrong moment, you risk leaking memory or even causing a deadlock.
It would be possible through JNI, under Windows there is a TerminateThread API that you can call, there is (hopefully) probably a similar thing under Android. The trouble will be getting the thread's native handle, you would need to obtain that when your user "program" is first loaded, probably by calling another JNI method from the thread in question as part of the initialisation process and getting the current thread handle from that.
I have not tried this myself, best case is that this "works" and kills the thread, but it is going to cause that thread to leak resources. Worst case is that it will leave the JVM in an inconsistent state internally, which will probably crash your entire application.
I really think this is a Bad Idea.
A better design, if you want to allow this, is to run your user code in another process and communicate with it via sockets or pipes. This way you can relatively safely terminate the other process if necessary. It's more work, but it's going to be a lot better in the long run.
You shold use Thread.interrupt().

How to terminate a Java process from a different one?

I am making a CSP solver that calculates all the combinatory solutions of a specific problem like this (briefly put):
// Say we are in a Solver class
public void solve() {
// find solution...
}
// This would be in a Problem class
problem.getSolver().solve();
There is a good chance that the resolution process takes a long time to finish, like more than a couple of minutes. So far, when it has been taking so long I have just stopped the process via console.
But eventually I am going to post my application as a web application in a host that allows Java apps (side-question: I have seen I can do it in Google Cloud and I have been told also about AWS; are they good options?). This means I, or the user, cannot terminate the process anymore if it takes too long.
I want to add the funcionality of having the option of cancelling the resolution process at will.
So I would declare a new method in the Solver class that would terminate the process, which would effectively stop the resolution process:
public void stopResolutionProcess() {
// kill the process, therefore, stop the resolution process
}
I cannot just call problem.getSolver().stopResolutionProcess() after the resolution process has already started, because the thread is already running and until that process ends, that method call will never be executed.
So how could I do this? How could a client signal the service hosted in the cloud to terminate a running process?
Put the long running process in a different thread. You can stop it from the main thread if necessary. See:
How to stop a thread by another thread?
Since you haven't chosen a cloud host yet this question is really difficult to answer. Generally speaking you need a synchronization object. Something like
volatile boolean keepRunning = true;
and your method would do
public void stopResolutionProcess(){
keepRunning = false;
}
then in your solve you have to regularly check for that variable
public void solve(){
while(keepRunning){
// doSomething();
Thread.sleep(500);
}
}
Now i use a variable here but that may not be sufficient. In App Engine your application could run in different instances where static variables are not synchronized. You would need a sync object that is accessible to all your solve threads. In App Engine that would be a datastore object that is also cached in the memcache. But you could use Pub/Sub or other mechanisms to propagate the completion of the task. The specifics are tightly coupled to the environment you'll choose to run this on.
Requests for product recommendations are generally off-topic on Stackoverflow. Choose a product for hosting and if you run into trouble return with a more concrete question.

Exiting one thread closes all

I have a java app which has a menu. One of the menu items is Exit. Which is defined as follows:
item_exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
Another menu item is New, which makes another instance (?) of the same program run in parallel. It is defined as follows:
item_new.addActionListener(new ActionListener() {
MyApp app = new MyApp();
app.start();
}
});
It works as desired except for one problem. It's that when I close one of them, both of them close. The entire app is built on one JFrame object. I don't think changing the default close operation of it will help. I think the issue is with system.exit(0). But, what is the alternative to fix this? I only want the thread I closed to close, not all of them. Thanks.
Creating an object and callings its start() method doesn't make another program run in parallel. It only creates an object, in the same JVM, and executes its start() method, in the same JVM.
System.exit() exits the JVM, so everything running in this JVM stops running.
To make a JFrame invisible, you call setVisible(false) on it. That won't stop the JVM.
System.exit(0); makes the entire Java machine to quit, with everything that is running within. Try not to use this, unless you really need this to happen.
For quitting, perhaps try checking this How to close a Java Swing application from the code
System.exit(0) quits the complete program, not only the current thread. If you want to quit a thread, you have two options: a thread automatically quits as soon as the corresponding Runnables run() method finishes, or you can kill the thread using thread.stop() (just for completeness, shouldn't be used).
Please read the documentation for System.exit(). It specifically states:
Terminates the currently running Java Virtual Machine.
This means the JVM will terminate, and all of your threads with it.
System.exit(0) shuts the whole JVM down.
Your two instances run on the same JVM : you don't fork a process, you just create another instance of your MyApp class. So it is obvious that both "applications" will be killed.
Instead of calling System.exit(0), you should send a termination signal to the JFrame you want to close
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
This way, only that JFrame (or "application") will be killed.
Another option would be to fork a whole new process. For that, I recommend you take a look at the Process class.
Basically, you'll need to change the action of "Exit" so that it's able to detect when there's another "app" currently running ... and to do something plausible in that case. Maybe you alert the user that the other activity hasn't finished yet, and warn him that if he really wants to exit now, the other activity will be abandoned. Maybe you launch the other activity in such a way that it is altogether separate and therefore doesn't care. There are several good alternatives, so this really becomes a design decision on your part: what strategy makes the most intuitive sense for you, and for your users?

Windows: signaling a Java process to show its window

I have a Java process that runs in the background. How can I quickly signal the process to show its window? I want a really light-weight script that can do this and can be launched from the Start Menu.
I think maybe a BAT file that checks if the lock file has been touched in the last few seconds, signal the process, otherwise, create a new one. The signal could be by creating another file that the process would be listening for.
That works, but it seems inefficient. Hesitation sounds unavoidable.
I could use Java instead of a BAT file, still that leaves the question of how to signal the background process. This only has to work in Windows, but I am good with Java so that is what I am using.
Any ideas?
One option would be to have that process having a listener on a port (as an example 8888), then you could send a message to that port (or do something like telnet localhost 8888). The running processes could have a separate thread listening on that port.
Another option would be to use JMX communication with the JVM - see http://download.oracle.com/javase/6/docs/technotes/guides/management/agent.html
Is there anything preventing you from checking the lock file from your Java process? You could use the Observer pattern to alert the main thread (or which ever thread) to changes in the file.
For example:
public class FileWatcher implements Observable {
private long lastModified;
private final File file;
public FileWatcher(File f) {
this.file = f;
this.lastModified = file.lastModified();
Thread t = new Thread() {
public void run() {
while(!stopThread) {
if(lastModified < file.lastModified()) {
lastModified = file.lastModified();
setChanged();
notifyObservers();
}
Thread.currentThread().sleep(5);
}
}
};
t.start();
}
}
DISCLAIMER: not tested or verified at all, but I'm sure you get the idea.
EDIT: oops, forgot the loop.
EDIT: new idea.
I have another idea. (I know you already accepted an answer, but I wanted to throw this out there.) Would it be possible to use the select function? In my very limited skim of the MSDN docs, this is only mentioned this in the context of sockets. I know the Linux equivalent is applicable to any file descriptor.
Instead of simply polling the file in the thread I mentioned above, let the OS do it! Pass the file into the writefds set to select and then it'll return when the file is modified. This means your process isn't spending valuable CPU time waiting for changes to the file.
I haven't verified whether or not Java exposes this call in the JDK, so it might require writing a JNI interface to get it to work. My knowledge in this area is a little fuzzy, sorry.
EDIT again again:
Found it! Java's Selector class looks like it implements select. Unfortunately, FileChannel isn't selectable, which is probably required in this case. :(

Java while loop and Threads! [duplicate]

This question already has answers here:
How can I abort a running JDBC transaction?
(4 answers)
Closed 5 years ago.
I have a program that continually polls the database for change in value of some field. It runs in the background and currently uses a while(true) and a sleep() method to set the interval. I am wondering if this is a good practice? And, what could be a more efficient way to implement this? The program is meant to run at all times.
Consequently, the only way to stop the program is by issuing a kill on the process ID. The program could be in the middle of a JDBC call. How could I go about terminating it more gracefully? I understand that the best option would be to devise some kind of exit strategy by using a flag that will be periodically checked by the thread. But, I am unable to think of a way/condition of changing the value of this flag. Any ideas?
I am wondering if this is a good practice?
No. It's not good. Sometimes, it's all you've got, but it's not good.
And, what could be a more efficient way to implement this?
How do things get into the database in the first place?
The best change is to fix programs that insert/update the database to make requests which go to the database and to your program. A JMS topic is good for this kind of thing.
The next best change is to add a trigger to the database to enqueue each insert/update event into a queue. The queue could feed a JMS topic (or queue) for processing by your program.
The fall-back plan is your polling loop.
Your polling loop, however, should not trivially do work. It should drop a message into a queue for some other JDBC process to work on. A termination request is another message that can be dropped into the JMS queue. When your program gets the termination message, it absolutely must be finished with the prior JDBC request and can stop gracefully.
Before doing any of this, look at ESB solutions. Sun's JCAPS or TIBCO already have this. An open source ESB like Mulesource or Jitterbit may already have this functionality already built and tested.
This is really too big an issue to answer completely in this format. Do yourself a favour and go buy Java Concurrency in Practice. There is no better resource for concurrency on the Java 5+ platform out there. There are whole chapters devoted to this subject.
On the subject of killing your process during a JDBC call, that should be fine. I believe there are issues with interrupting a JDBC call (in that you can't?) but that's a different issue.
As others have said, the fact that you have to poll is probably indicative of a deeper problem with the design of your system... but sometimes that's the way it goes, so...
If you'd like to handle "killing" the process a little more gracefully, you could install a shutdown hook which is called when you hit Ctrl+C:
volatile boolean stop = false;
Runtime.getRuntime().addShutdownHook(new Thread("shutdown thread") {
public void run() {
stop = true;
}
});
then periodically check the stop variable.
A more elegant solution is to wait on an event:
boolean stop = false;
final Object event = new Object();
Runtime.getRuntime().addShutdownHook(new Thread("shutdown thread") {
public void run() {
synchronized(event) {
stop = true;
event.notifyAll();
}
}
});
// ... and in your polling loop ...
synchronized(event) {
while(!stop) {
// ... do JDBC access ...
try {
// Wait 30 seconds, but break out as soon as the event is fired.
event.wait(30000);
}
catch(InterruptedException e) {
// Log a message and exit. Never ignore interrupted exception.
break;
}
}
}
Or something like that.
Note that a Timer (or similar) would be better in that you could at least reuse it and let it do with all of the details of sleeping, scheduling, exception handling, etc...
There are many reasons your app could die. Don't focus on just the one.
If it's even theoretically possible for your JDBC work to leave things in a half-correct state, then you have a bug you should fix. All of your DB work should be in a transaction. It should go or not go.
This is Java. Move your processing to a second thread. Now you can
Read from stdin in a loop. If someone types "QUIT", set the while flag to false and exit.
Create a AWT or Swing frame with a STOP button.
Pretend you are a Unix daemon and create a server socket. Wait for someone to open the socket and send "QUIT". (This has the added bonus that you can change the sleep to a select with timeout.)
There must be hundreds of variants on this.
Set up a signal handler for SIGTERM that sets a flag telling your loop to exit its next time through.
Regarding the question "The program could be in the middle of a JDBC call. How could I go about terminating it more gracefully?" - see How can I abort a running jdbc transaction?
Note that using a poll with sleep() is rarely the correct solution - implemented improperly, it can end up hogging CPU resources (the JVM thread-scheduler ends up spending inordinate amount of time sleeping and waking up the thread).
I‘ve created a Service class in my current company’s utility library for these kinds of problems:
public class Service implements Runnable {
private boolean shouldStop = false;
public synchronized stop() {
shouldStop = true;
notify();
}
private synchronized shouldStop() {
return shouldStop;
}
public void run() {
setUp();
while (!shouldStop()) {
doStuff();
sleep(60 * 1000);
}
}
private synchronized sleep(long delay) {
try {
wait(delay);
} catch (InterruptedException ie1) {
/* ignore. */
}
}
}
Of course this is far from complete but you should get the gist. This will enable you to simply call the stop() method when you want the program to stop and it will exit cleanly.
If that's your application and you can modify it, you can:
Make it read a file
Read for the value of a flag.
When you want to kill it, you just modify the file and the application will exit gracefully.
Not need to work it that harder that that.
You could make the field a compound value that includes (conceptually) a process-ID and a timestamp. [Better yet, use two or more fields.] Start a thread in the process that owns access to the field, and have it loop, sleeping and updating the timestamp. Then a polling process that is waiting to own access to the field can observe that the timestamp has not updated in some time T (which is much greater than the time of the updating loop's sleep interval) and assume that the previously-owning process has died.
But this is still prone to failure.
In other languages, I always try to use flock() calls to synchronize on a file. Not sure what the Java equivalent is. Get real concurrency if you at all possibly can.
I'm surprised nobody mentioned the interrupt mechanism implemented in Java. It's supposed to be a solution to the problem of stopping a thread. All other solutions have at least one flaw, that's why this mechanism is needed to be implemented in the Java concurrency library.
You can stop a thread by sending it an interrupt() message, but there are others ways that threads get interrupted. When this happens an InterruptedException is thrown. That's why you have to handle it when calling sleep() for example. That's where you can do cleanup and end gracefully, like closing the database connection.
Java9 has another "potential" answer to this: Thread.onSpinWait():
Indicates that the caller is momentarily unable to progress, until the occurrence of one or more actions on the part of other activities. By invoking this method within each iteration of a spin-wait loop construct, the calling thread indicates to the runtime that it is busy-waiting. The runtime may take action to improve the performance of invoking spin-wait loop constructions.
See JEP 285 for more details.
I think you should poll it with timertask instead.
My computer is running a while loop 1075566 times in 10 seconds.
Thats 107557 times in one second.
How often is it truly needed to poll it? A TimerTask runs at its fastest 1000 times in 1 second. You give it a parameter in int (miliseconds) as parameters. If you are content with that - that means you strain your cpu 108 times less with that task.
If you would be happy with polling once each second that is (108 * 1000). 108 000 times less straining. That also mean that you could check 108 000 values with the same cpu strain that you had with your one while loop - beause the you dont assign your cpu to check as often. Remember the cpu has a clock cycle. Mine is 3 600 000 000 hertz (cycles per second).
If your goal is to have it updated for a user - you can run a check each time the user logs in (or manually let him ask for an update) - that would practically not strain the cpu whatsoever.
You can also use thread.sleep(miliseconds); to lower the strain of your polling thread (as it wont be polling as often) you where doing.

Categories

Resources