I'm in need of a requirement which is like as follows.
I have a jsp contains enable and disable radio buttons.
if i click on enable, a process should execute with an interval of time like for each and every 2 or 3 hours.
if disable is clicked and submitted, the
current executing task should pause until and unless again the enable
is submitted/clicked from the jsp(if enabled the above step should
continue to execute).
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
//first time execution
if(request.getParameter("lic").equals("enable") && counter==0)
{
t1.start();
counter++;
System.out.println(counter);
}
//if already started and clicks re-enable
else if(request.getParameter("lic").equals("enable") && counter>0)
{
System.out.println("thread already started");
t1.interrupt();
}
//for long pausing of thread
else if(request.getParameter("lic").equals("disable"))
{
System.out.println("thread is going to pause");
try
{
Thread.sleep(20000);
System.out.println("slept for 20 seconds");
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
System.out.println("interrupted while sleeping");
}
}
}
static int counter = 0;
static Thread t1 = new Thread()
{
public void run()
{
System.out.println("hi thread is executed");
}
};
}
Related
My Java code creates a thread on button click.
Every time if the button is clicked a thread is created.
I want to kill the previous thread if button is clicked again.
how can I do this?
below is the portion of code inside buttonclicklistener
myThread= new Thread()
{
public void run() {
diff2 = Math.abs(d3.getTime() - d1.getTime());
long diffseconds = diff2 /1000;
final long start = System.currentTimeMillis()/1000;
tv_timecount=(TextView)findViewById(R.id.tv_timeCount);
while(diffseconds>0)
{
tv_timecount.setText(String.valueOf(diffseconds--));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(myThread.isInterrupted())
break;
}
}
};
myThread.start();
I want to stop this Thread.
Many ways,
1: Using deprecated stop
Thread t = new Thread();
t.start();
t.stop(); //this is deprecated but it stops the thread
2: Using interrupt
Thread t = new Thread();
t.start();
t.interrupt();
3: Killing a thread with a while loop
boolean running = true;
Thread t = new Thread(() -> {
while (running) {
System.out.println("Running");
try { Thread.sleep(100); } catch (Throwable t) {}
}
});
t.start();
running = false;
You didn't mention why exactly you can't stop the thread, so I've some assumes which problems you might have.
1.Main reason why interrupt doesn't work in your code is because you catch InterruptedException and do noghing about that. But you should set interrupted flag by yourself after that, using Thread.currentThread().interrupt()
2.You can click the button 2 or more times at the same time, so all the clicks will try to stop the same thread, but every of them then start their own thread, so all but one of these thread (or pointer to them) will leak from you. This can be solved using synchronized function.
The general code, which handles button click should be looking like the code below:
private Thread myThread;
private synchronized void buttonClick() throws InterruptedException //NOTE synchronized
{
if (myThread != null) {
myThread.interrupt();
myThread.join();
}
myThread = new Thread(() -> {
diff2 = Math.abs(d3.getTime() - d1.getTime());
long diffseconds = diff2 / 1000;
final long start = System.currentTimeMillis() / 1000;
tv_timecount = (TextView) findViewById(R.id.tv_timeCount);
while (diffseconds > 0) {
tv_timecount.setText(String.valueOf(diffseconds--));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // NOTE: flag interrupt gets set
}
if (myThread.isInterrupted())
break;
}
});
}
Best way would be to use a flag. Introduce a flag inside your while method Add logic to check if flag is set and only then execute the code in your while loop.
while(diffseconds>0)
{
synchronized(Object.class){
if(flag == set) break;
}
//your code
}
You can reset/set flag on button click from other threads or the main execution.
the main problem is that I don't know how long my method will take to finish, I have 2 threads, one to execute the method that do stuff and the other one excute the progress of the progress bar, this is my first thread:
#Override
public void run() {
//This is a static variable, indicate when the method analyzeSentence finish
finish = false;
String sentence = analyzeSentence();
try {
Thread.sleep( 1000 );
} catch (InterruptedException e){
System.err.println( e.getMessage() );
}
finish = true;
}
And in my second thread (the progress bar thread) I have this:
#Override
public void run() {
i = 1;
while(!Analyze.finish) {
i = (i > 100) ? 1 : i+1; //Here I have the problem
progressBar.setValue(i);
progressBar.repaint();
try {
Thread.sleep(this.value);
} catch (InterruptedException e) {
System.err.println(e.getMessage());
}
if(Analyze.finish) {
progressBar.setValue(100);
break;
}
}
}
The problem is that the progress bar reset their values to zero but the method still not over so the progress bar is filled again and again... Is there any way to obtain the lenght of the time that the method takes to finish?
I just want to display the values of each iteration in the loop proceeded by 2 seconds delay.
when i run the code, the main thread freezes and after a while only the value of tv_t1: 19 is displayed.
can anyone please let me know what is the error or what i am missing in the below posted code?
NOTE :
I would like to do so on the main thread.
*Code
tv_t1 = (TextView) findViewById(R.id.tv_t1);
tv_t2 = (TextView) findViewById(R.id.tv_t2);
for(int i = 0; i < 20; i++) {
tv_t1.setText("t1:" + i);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Thread is Android's main/UI thread, and setting sleep(value) causes the main thread to sleep or
to stop doing its work for a scheduled time. If you want to update the main UI and sleep for a while, it is better to create a new thread and then create Runnable object that overrides Run(). And inside Run() you can call the function that is time consuming or also you can cause the new thread you created to sleep instead of forcing the UI thread to sleep which will cause all the main UI elements to freeze. The Handler in the below code works as intermediate between the thread and the message queue, you can also replace h1 with your tv_1 to post that as message into the queue and subsequently to update your view.
Please try the below code:
Handler h1 = new Handler();
Thread t1;
t1 = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
loop();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t1.start();
protected void loop() throws InterruptedException {
// TODO Auto-generated method stub
for (i = 0; i < 20; i++) {
t1.sleep(2000);
h1.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
tv_t1.setText("tv_1: " + i);
}
});
}
}
Thread.sleep on the UI Thread is a bad idea. Use an handler:
private Handler mHandler = new Handler():
private class MyRunnable implmenets Runanble {
private final static int MAX_INT = 20;
private int mCounter = 0;
#Override
public void run() {
if (mCounter == 20) {
mHandler.removeCallbacks(this);
return;
}
mytexts.setText(" " + mCounter);
mCounter++;
mHandler.postDelayed(this, 2000);
}
}
and in your create, after you initialze your views, call
mHandler.postDelayed(new MyRunnable(), 2000);
Maybe this will work out:
for(int i = 0; i < 20; i++) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
tv_t1.setText("t1:" + i);
}
}, 2000);
}
And yes if you get a delay when the value of "i" was 0 then set the first text outside the loop and start the loop with i=1 or put an if-else block inside the loop
Hope it helped.
Im a beginner to GUI and multithreading. I currently have a simulation which runs through a bug moving about in the console. I want to be able to pause the bug using a button. I have two buttons (run and pause) the run button will start the simulation and the pause button should pause it ( or make it sleep for a bit) ive managed to get the run button working but i am then unable to click pause once its running (because its in the same thread i believe) Ive read into it alot but still cant seem to work it out.. any help would be massively appreciated..
//IN MY ACTION LISTENER..
else if (E.getSource() == Pause) {
Worker pauseWorker = new Worker();
pauseWorker.execute();
IN MY NEW WORKER CLASS
import javax.swing.SwingWorker;
public class Worker extends SwingWorker<Void, Void> {
#Override
protected Void doInBackground() throws Exception {
// System.out.println("Background");
for (int i = 0; i <= 1; i++) {
Thread.sleep(1000);
System.out.println("Background running");
}
return null;
}
}
else if (E.getSource() == Pause) {
Worker pauseWorker = new Worker();
pauseWorker.execute();
This starts a new worker, does not stop the running one.
Instead, you can keep a reference to the background worker and cancel() it when the pause button is pressed. See SwingWorker.cancel()
else if (E.getSource() == Pause) {
worker.cancel(true);
}
And in the worker class, regularly check if you've been cancelled:
#Override
protected Void doInBackground() throws Exception {
// System.out.println("Background");
while(!isCancelled()) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println("Background interrupted");
}
System.out.println("Background running");
}
return null;
}
If you really do need to pause rather than cancel the worker, you'll have to write your own pause() method and do the administration yourself.
To give you some idea, something like this goes into the worker class then:
boolean paused = false;
public void pause() {
paused = true;
}
public synchronized void resume() {
paused = false;
this.notify();
}
#Override
protected Void doInBackground() throws Exception {
while(!isCancelled()) {
if( paused ) {
System.out.println("Background paused, waiting for resume");
try {
synchronized(this){
wait(1000);
}
} catch (InterruptedException ex) {
System.out.println("Background interrupted");
}
} else {
System.out.println("Background running");
// do a chunk of actual work
}
}
return null;
}
I'm using a button to start a background service in my app. This is the code I'm using:
#Override
public void actionPerformed(ActionEvent action) {
if (action.getActionCommand().equals("Start")) {
while (true) {
new Thread(new Runnable() {
public void run() {
System.out.println("Started");
}
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
This does update the service every second, which it what I want. Problem is it freezes the rest of the application. How do I implement it so that that doesn't happen?
The following is likely to cause your application to pause:
while (true) {
...
}
Try removing those lines.
Edit: as per comment, to make the newly-launched thread fire every second, move the sleep and while loop inside the run() method:
if (action.getActionCommand().equals("Start")) {
new Thread(new Runnable() {
public void run() {
while (true) {
System.out.println("Started"); }
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
You're calling this method in the Thread that updates the GUI, and this you're pausing the GUI refresh. Spawn a new thread and execute that there.
an infinite loop ??
while (true) {.....}
how you supposed to get out of here -
add an print statement inside loop and you will come to know that you have been stuck here after button click
Ok I got it. Here's what I should have done:
#Override
public void actionPerformed(ActionEvent action) {
if (action.getActionCommand().equals("Start")) {
new Thread(new Runnable() {
public void run() {
while (true) {
System.out.println("Started");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}