具有 Java API 的 Linux 范围信号量
我需要防止某个应用程序功能与其自身同时运行。风险很大,因为此函数位于提交给 java.util.Timer 的代码中(在几个小时内每分钟重复一次),并且设置该函数的过程完成并返回到 bash 命令行。然后用户可以调用相同的程序。另一个风险来自拥有两个或多个控制台窗口的用户,他们错误地在两个控制台窗口中运行程序。
我认为带有 Java API 的操作系统范围的信号量可能可以解决这个问题。有这样的 Java 存档吗?
有人问我是否使用多个 JVM。我认为如果打开多个控制台,则意味着多个 JVM。
这是我使用 Java 的 Timer 和 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();
}
}
}
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();
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以在开始操作时在共享目录中创建一个 0 字节文件“methodname.LOCK”,并在完成后将其删除。在 Java 中使用 no recreate 标志创建它应该可以解决您的问题。
确保在“finally”块中删除它,这样您就永远不会处于文件存在的状态,并继续阻止进程永远运行
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.
我见过的唯一禁止同一程序的多个实例的标准 Java 功能是 Java WebStart 中的
SingleInstanceService
。http://download.oracle.com /javase/1.5.0/docs/guide/javaws/developersguide/examples.html#SingleInstanceService
它需要你为你的应用程序创建一个JNLP文件,这有点麻烦但无论如何可能对你非常有用。请注意,Java 不允许将命令行参数传递给您的程序,这在这种情况下可能非常不方便。取决于你的命令行所说的。
如果 Java WebStart 不适合您,那么您必须向操作系统请求后续请求被拒绝的资源,并自动释放它。其中唯一一个不特定于平台的是 TCP/IP 套接字,但这些套接字很少见,并且可能被其他程序使用。在 Linux 下你可能会要求共享内存,但我个人没有这方面的经验。
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.