I have developed an application which is intended to allow users to execute queries.Once the user enters the query and clicks on execute button the control is passed to RMI server which in turn starts the thread.
User should be able to execute other quesries one after the other and each query will b executed in different thread.
I am not able to stop the execution of the thread. I want to stop the execution while it is executing or on the button click event based on the thread id passed.
I am trying below code
public class AcQueryExecutor implements Runnable {
private volatile boolean paused = false;
private volatile boolean finished = false;
String request_id="",usrnamee="",pswd="",driver="",url="";
public AcQueryExecutor(String request_id,String usrnamee,String pswd,String driver,String url) {
this.request_id=request_id;
this.usrnamee=usrnamee;
this.pswd=pswd;
this.url=url;
this.driver=driver;
}
public void upload() throws InterruptedException {
//some code
stop();
//some more code
}
public void run() {
try {
while(!finished) {
upload();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void stop() {
finished = true;
}
}
RMI server class from where I start the thread
public class ExecutorServer extends UnicastRemoteObject implements ExecutorInterface
{
public ExecutorServer()throws RemoteException
{
System.out.println("Server is in listening mode");
}
public void executeJob(String req_id,String usrname,String pwd,String driver,String url)throws RemoteException
{
try{
System.out.println("Inside executeJob.wew..");
AcQueryExecutor a=new AcQueryExecutor(req_id,usrname,pwd,driver,url);
Thread t1 = new Thread(a);
t1.start();
}
catch(Exception e)
{
System.out.println("Exception " + e);
}
}
public void killJob(String req_id)throws RemoteException{
logger.debug("Kill task");
AcQueryExecutor a=new AcQueryExecutor(req_id,"","","","");
a.stop();
}
public static void main(String arg[])
{
try{
LocateRegistry.createRegistry(2007);
ExecutorServer p=new ExecutorServer();
Naming.rebind("//localhost:2007/exec1",p);
System.out.println ("Server is connected and ready for operation.");
}catch(Exception e)
{
System.out.println("Exception occurred : "+e.getMessage());
e.printStackTrace();
}
}
}
RMI client
ExecutorInterface p=(ExecutorInterface)Naming.lookup("//localhost:2007/exec1");
System.out.println("Inside client.."+ p.toString());
p.executeJob(id, usrname, pswd);
p.killJob(id);
}
Till my knowlegde p.killJob() will wont be invoked untill executeJob() is finished.
I want to stop the execution while it is running
The problem appears to be that you are allocating a fresh instance of the Runnable AcQueryExecutor for each thread. This means each is seeing its own finished flag. Setting one in killJob will not lead to any other thread exiting because no other thread shares this flag.
You'll need to share Runnables or else make the finish field static. The latter will cause all threads to exit whenever any instance's stop is called, so may not be what you want.
Related
I am new to the multithreading programming. I am having a problem in understanding the behaviour of synchronized method access by multiple instance of the class.
In the below code am trying to implement wait and poll mechanism. Where am waiting for a response from one service for some time and if that service returned response within that time i will return back.
In this I have implemented two synchronized blocks. I can understand that two threads cant able to access the synchronized method at the same time. Here only I can get confused what if multiple instances of WaitAndPoll class created and invoked at the same time.
Will each instance execute one by one. If that so it will affect the performance badly in that case can anyone advise how to simplify this ?
WAIT and POLL:
public class WaitAndPoll {
Model model;
OSBService osbService;
WaitAndPoll(Model model, OSBService th1){
this.model = model;
this.osbService=th1;
}
// Prints a string and waits for consume()
public void waitingForOSBResponse()throws InterruptedException
{
synchronized(this)
{
System.out.println("waitingForOSBResponse thread running "+this.model.str);
this.osbService.start();
wait();
if(this.model.str==null) { // checking the response is still null if so calling java function
this.osbService.interrupt(); //This will interupt osb service thread
System.out.println(" Calling the java function");
}else{
System.out.println(" Response successfully returned from the OSBService :: "+this.model.str);
}
}
}
//Polling for every 1 second
public void pollingOSBResponse()throws InterruptedException
{
Thread.sleep(200);
synchronized(this)
{
int count=0;
while(this.model.str == null && count<3){
wait(1000);
System.out.println("wating for the modification");
++count;
}
System.out.println("Polling completed");
notify();
}
}
}
OSBService:
import java.util.Date;
public class OSBService extends Thread{
Model model;
OSBService(Model model){
this.model= model;
}
public void run(){
System.out.println("calling the osb webservice:: "+this.model.str);
try {
Thread.sleep(5000); //Simulating the wating period for the response
this.model.str="modified";
System.out.println("called the osb webservice:: "+this.model.str);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.err.println("OSB service interrupted because of longer time for response ::: "+this.model.str+" :: "+new Date().toString());
}catch (Exception e){
e.printStackTrace();
}
}
}
Main class:
public class Main
{
public static void main(String[] args) throws InterruptedException
{
Model model = new Model();
model.str=null;
OSBService osbService = new OSBService(model);
final WaitAndPoll waitAndPoll = new WaitAndPoll(model,osbService);
//Calling the OSB service and waiting for its response
Thread t1 = new Thread(new Runnable()
{
#Override
public void run()
{
try
{
waitAndPoll.waitingForOSBResponse();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
});
//Polling whether the osb reponse received or not
Thread t2 = new Thread(new Runnable()
{
#Override
public void run()
{
try
{
waitAndPoll.pollingOSBResponse();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
If multiple instance are created, then the methods will be try to acquire mutex lock in synchronized block on different instances of the WaitAndPoll class.
If you are passing different instances to the threads then there is no guarantee which thead will execute first the synchronized block.
I was tasked to write a small server application. It is supposed to be started via the console and then run in the background, processing some network traffic and calculating stuff locally until it receives a shutdown signal. I am pretty sure i can handle all of that - except the very basic application architecture. I am super unsure how to bring my main loop to wait for the application to finish. So here is my current code, cleaned up and omitting unnecessary parts.
public class TestServer {
public static Logger logger;
private static Boolean abortStartup = false;
private static ServerModule server;
public static void main(String[] args) {
System.out.println("Starting Server...");
initializeServer(); //this function reads config file, and initializes all variables and stuff. If anything goes wrong, abortStartup is set to true
if (!abortStartup) {
runMainLoop();
}
if (!abortStartup) {
cleanup(); //clean up all initialized variables and objects
}
System.out.println("Goodbye.");
}
private static void runMainLoop() {
//This is the main loop. Run this until application terminates.
logger.log(null, "Starting main loop...", Logger.LOGLEVEL_NOTE);
server.run();
while (server.isAlive()) {
//wait until server dies.
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
logger.log(null, "Interrupted during wait for main thread.", Logger.LOGLEVEL_ERROR);
}
}
logger.log(null, "Done.", Logger.LOGLEVEL_NOTE);
}
ServerModule looks like this:
public class ServerModule{
public Boolean shutdown = false;
private Boolean stayAlive = true;
public ServerModule(){
//setup everything
}
public void run() {
//initalize timers, instantiate objects etc.. add listeners and everything. At some point, a network message will set stayAlive to false;
}
public Boolean isAlive() {
return stayAlive;
}
Now for the actual question: is there a more elegant or more efficient way to go about this? i am talking about this part specifically:
while (server.isAlive()) {
//wait until server dies.
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
logger.log(null, "Interrupted during wait for main thread.", Logger.LOGLEVEL_ERROR);
}
Is thread.sleep okay here? Could or should i even omit it? I want to wait here at this very point of my code, so i can clean up after execution stops.
You can make your server something runnable, pack that into a Thread and join!
Example
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("Starting Server!");
t.start();
t.join();
System.out.println("Server is done!");
}
Also you can use CountDownLatch for your purpose, see example:
public class ServerModule extends Thread {
private final CountDownLatch latch;
ServerModule(CountDownLatch latch) {
this.latch = latch;
}
#Override
public void run() {
try {
Thread.sleep(1000L);
//decrease counter of the latch when job is done
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// as ctor arg use threads count for countdown
CountDownLatch latch = new CountDownLatch(1);
System.out.println("Start server");
ServerModule serverModule = new ServerModule(latch);
serverModule.start();
try {
//waiting until latch count will be 0
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Server is done");
}
}
Also with CountDownLatch you can create multiple server instances and waiting them in main thread until they are all done.
It depends on how you're managing your threads.
At the lowest level Java thread API, your main thread can wait for the server thread to complete with:
serverThread.join();
Look at the Thread API for more options, such as putting a timeout on the join() (so you can take increasingly drastic measures to make it end).
Higher level threading abstractions such as Executor, Future, ForkJoinTask etc. give you the same ability with different APIs. A thorough exploration of these is beyond the scope of a SO answer -- Oracle has tutorials on concurrency, or there are books.
I want to make a single thread which would contain 3 infinite tasks.
I want one task to run at a time and start/stop running task when required.
For example first I want task 1 to run, then I want task 2 to run but after stopping task 1 and again I want task 1 to run but after stopping of task 2 and so on.
Infinite task needs to check some condition and if that condition is satisfied perform some operations and if not satisfied sleep for few seconds and after wake up perform the above same operations again.
Infinite Runnable task looks some thing like this:
new Runnable(){
while(1){
if(TaskQueue.getInstance().size()<= 100){
TaskQueue.getInstance().push("add command to the end of queue");
}else{
try {
Thread.sleep(10000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Any help would be appreciated?
Edit : I modified my question. I want a continuous single running thread(some thing like looper ) to monitor 3 infinite tasks and control this single continuous running thread tasks from outside.
Use this for start/stop thread in real-time:
class MyThread extends Thread {
private volatile boolean running = true; // Run unless told to pause
...
#Override
public void run() {
// Only keep painting while "running" is true
// This is a crude implementation of pausing the thread
while (true) {
if (Thread.currentThread().isInterrupted()) {
return;
}
if (running) {
//Your code
} else yield;
}
}
public void pauseThread() throws InterruptedException {
running = false;
}
public void resumeThread() {
running = true;
}
}
For pause thread use this:
myThread.pauseThread();
For resume thread use this:
myThread.resumeThread();
For stop thread use this (Not recommended):
myThread.stop();
For currently stop thread use this:
myThread.interrupt();
You must use a class like Thread that already implements Runnable.
new Thread(){....};
And the way it works it's:
Thread t = new Thread(){.....};
t.start();
t.stop();
You could also initialize a new thread, like:
Thread exampleThread = new thread();
After this you can start it at any point in your code by:
exampleThread.start();
you can use Semaphore,
to Manage the amount of signal.
private final static Semaphore semaphore = new Semaphore(0);
public static void main(String[] args) throws Exception {
//入口
threadTest();
}
public static void thread1() {
try{
//…… some code
}
finally{
semaphore.release();
}
}
public static void thread2() {
semaphore.acquire(1);
}
The question is my first answer,thanks.
I finally made my task scheduler. The API of which looks something like this:
TaskScheduler taskScheduler = TaskScheduler.getInstance();
taskScheduler.startTaskOne();
taskScheduler.stopTaskOne();
taskScheduler.startTaskTwo();
taskScheduler.stopTaskTwo();
Runs one task at a time (because I used Executors.newSingleThreadExecutor()).
We can control the execution of the task from outside:
public class TaskScheduler {
private static ExecutorService mTaskRunningService;
private static TaskScheduler mInstance;
private Future mFirstTaskFuture = null;
private Future mSecondTaskFuture = null;
static {
configure();
}
private static void configure() {
mTaskRunningService = Executors.newSingleThreadExecutor();
}
public static TaskScheduler getInstance() {
if (mInstance == null) {
mInstance = new TaskScheduler();
}
return mInstance;
}
private Runnable mTaskOneRunnable = new Runnable() {
#Override
public void run() {
try {
while (true) {
/** stop this single thread (i.e executing one task at time) service if this thread is interrupted
* from outside because documentation of {#link java.util.concurrent.ThreadPoolExecutor#shutdownNow()}
* says we need to do this*/
if (Thread.currentThread().isInterrupted()) {
return;
}
// task one work.......
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
private Runnable mTaskTwoRunnable = new Runnable() {
#Override
public void run() {
try {
while (true) {
/** stop this single thread (i.e executing one task at time) service if this thread is interrupted
* from outside because documentation of {#link java.util.concurrent.ThreadPoolExecutor#shutdownNow()}
* says we need to do this*/
if (Thread.currentThread().isInterrupted()) {
return;
}
// task two work......
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
public synchronized void startTaskOne() {
if (mFirstTaskFuture == null) {
// start executing runnable
mFirstTaskFuture = mTaskRunningService.submit(mTaskOneRunnable);
}
}
public synchronized boolean stopTaskOne() {
if (mFirstTaskFuture != null) {
// stop general reading thread
mFirstTaskFuture.cancel(true);
// cancel status
boolean status = mFirstTaskFuture.isDone();
// assign null because startTaskOne() again be called
mGeneralFuture = null;
return status;
}
return true;
}
public synchronized void startTaskTwo() {
if (mSecondTaskFuture == null) {
// start executing runnable
mSecondTaskFuture = mTaskRunningService.submit(mTaskTwoRunnable);
}
}
public synchronized boolean stopTaskTwo() {
if (mSecondTaskFuture != null) {
// clear task queue
mTaskQueue.clearTaskQueue();
// stop 22 probes reading thread
mSecondTaskFuture.cancel(true);
// cancel status
boolean status = mSecondTaskFuture.isDone();
// assign null because startTaskTwo() again be called
mSecondTaskFuture = null;
return status;
}
return true;
}
}
In the Java tutorial it says about try { ... } finally { ... }:
Note: If the JVM exits while the try or catch code is being executed,
then the finally block may not execute. Likewise, if the thread
executing the try or catch code is interrupted or killed, the finally
block may not execute even though the application as a whole
continues.
Is it true that a thread can be interrupted or killed (I thought that was impossible?) such that the finally block will not be executed while the JVM running this thread is not exited/killed? (I am puzzled because the quote above is pretty explicit about this, not much room for misunderstanding.)
Edit: Broke the question down to its core intend.
Well, I stand corrected. It is possible by using deprecated methods:
#Test
public void testThread() throws Exception {
Thread thread = new Thread(new MyRunnable());
thread.start();
Thread.sleep(100);
thread.suspend();
Thread.sleep(2000);
}
class MyRunnable implements Runnable {
#Override
public void run() {
System.out.println("Start");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("Done");
}
}
}
Due to the pausing which will (most likely) occure while the thread is asleep, the finally block will never be executed.
Rafael, I believe this is one of the edge cases you are after. If a thread is blocked on something native (eg reading from STDIN or a Socket), and the JVM is in a state of shutdown, and the thread is interrupted, then finally may not be invoked.
The following example indicates this without invoking deprecated methods:
Sleep - finally is invoked.
SystemIn - finally is not invoked.
The example is very contrived, and is purely provided for demonstrative purposes :)
public class Interrupted {
static final List<Thread> THREADS = Arrays.asList(
new Thread(new Sleep()),
new Thread(new SystemIn())
);
static final CountDownLatch LATCH = new CountDownLatch(THREADS.size());
public static void main(String[] args) throws Exception {
Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook()));
for (Thread thread : THREADS) {
thread.start();
}
System.out.println("[main] Waiting for threads to start...");
LATCH.await();
System.out.println("[main] All started, time to exit");
System.exit(0);
}
static abstract class BlockingTask implements Runnable {
#Override
public void run() {
final String name = getClass().getSimpleName();
try {
LATCH.countDown();
System.out.printf("[%s] is about to block...%n",name);
blockingTask();
} catch (Throwable e) {
System.out.printf("[%s] ", name);
e.printStackTrace(System.out);
} finally {
System.out.printf("[%s] finally%n", name);
}
}
abstract void blockingTask() throws Throwable;
}
static class Sleep extends BlockingTask {
#Override
void blockingTask() throws Throwable {
Thread.sleep(60 * 60 * 1000); // 1 hour
}
}
static class SystemIn extends BlockingTask {
#Override
void blockingTask() throws Throwable {
System.in.read();
}
}
static class ShutdownHook implements Runnable {
#Override
public void run() {
System.out.println("[shutdown-hook] About to interrupt blocking tasks...");
for (Thread thread : THREADS) {
thread.interrupt();
}
System.out.println("[shutdown-hook] Interrupted");
try {
for (int i=0; i<10; i++) {
Thread.sleep(50L);
System.out.println("[shutdown-hook] Still exiting...");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Hi I'm using the next code to try to stop a thread, but when I see that Running is false it becomes true again.
public class usoos {
public static void main(String[] args) throws Exception {
start();
Thread.sleep(10000);
end();
}
public static SimpleThreads start(){
SimpleThreads id = new SimpleThreads();
id.start();
System.out.println("started.");
return id;
}
public static void end(){
System.out.println("finished.");
start().shutdown();
}
}
And the thread
public class SimpleThreads extends Thread {
volatile boolean running = true;
public SimpleThreads () {
}
public void run() {
while (running){
System.out.println("Running = " + running);
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {}
}
System.out.println("Shutting down thread" + "======Running = " + running);
}
public void shutdown(){
running = false;
System.out.println("End" );
}
}
The problem is that when I try to stop it(I set running to false), it starts again..
Look at this line in the end method:
start().shutdown();
You are not stopping the original instance; you are starting another one, which you then immediately shut down.
There is no connection between your start and end methods—no information, no reference is passed from one to the other. It is obviously impossible to stop the thread you started in the start method.
Your end method should not be static; in fact, you don't even need it, shutdown is already it:
SimpleThreads t = start();
Thread.sleep(10000);
t.shutdown();
Because in the end method you just create a new Thread and kill it, save the thread instance and kill it:
Your code should look something like this:
public class usoos {
public static void main(String[] args) throws Exception {
SimpleThreads id = start();
Thread.sleep(10000);
end(id);
}
public static SimpleThreads start(){
SimpleThreads id = new SimpleThreads();
id.start();
System.out.println("started.");
return id;
}
public static void end(SimpleThreads id){
System.out.println("finished.");
id.shutdown();
}