The thread cannot stop

why can't my thread be stopped ???

class Threadz { class runP implements Runnable { int num; private volatile boolean exit = false; Thread t; public runP() { t = new Thread(this, "T1"); t.start(); } @Override public void run() { while(!exit) { System.out.println(t.currentThread().getName()+": "+num); num++; try { t.sleep(200); } catch(InterruptedException e) {} } } public void stop() { exit = true; } } public static void main(String[] a) { runP rp = new Threadz().new runP(); if(rp.num == 1) {rp.stop();} } } 

If I use rp.num == 0, the stream can be stopped immediately. But why, when I changed rp.num == x (x is any number greater than 0), the stream cannot stop? help me solve this thing ... thanks for any tips.

+5
source share
4 answers

Since this code is not executed in the run () method of the thread:

  runP rp = new Threadz().new runP(); if (rp.num == 1) { rp.stop(); } 

It works with 0 because the default value for int is 0. But this is not necessarily true in all executions of the application, since the runP thread can start and increase num before checking: if (rp.num == 0)

Move the break condition in the runP thread start method:

 @Override public void run() { while(!exit) { System.out.println(t.currentThread().getName()+": "+num); num++; try { t.sleep(200); } catch(InterruptedException e) {} if (rp.num == 1) { exit = true; } } } 
+3
source

I am sure that if you run the program many times, this will be the case when the program actually stops.

The reason that you run the program is much more likely to run

 if(rp.num == 1) {rp.stop();} 

to num++ in your run() method the value changes.

However, by chance you may encounter a case where a loop in your start method executes before this if statement in your main method.

one way to make sure this is happening is to constantly check the status:

eg.

 public static void main(String[] a) { runP rp = new Threadz().new runP(); while(true){ if(rp.num == 1) { rp.stop(); break; } } } 
0
source

The statement below is executed before the thread starts executing the execution method.

 if(rp.num == 1) {rp.stop();} 

Add Thread.sleep before the above statement, it works fine because it will execute this statement after the loop starts.

  public static void main(String[] a) { runP rp = new Threadz().new runP(); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(rp.num > 1) {rp.stop();} } 

I made it> 1 to check.

0
source

The rp.num == 1 check should happen exactly at the point where rp.num is exactly one, which is unlikely.

In your main method, you start a thread that increments num every 200 ms. Subsequently, you check whether there is num == 1 , but when exactly this code is executed depends on many factors that you cannot control (OS planning, etc.). It can be after 10 ms (where the value will be 1), but it can also be after 300 ms (when the value is already 2). Also, when a thread is exactly running, it is not sure. Therefore, it is also possible that your thread starts only after the test. You can easily check this by replacing the check if(rp.num == 1) {rp.stop()}; to the simple print statement System.out.println(rp.num) . If you additionally wait some time before printing, you can get a better idea of ​​what I'm talking about.

Suppose you want to stop runnable from the outside, I suggest using something like an observer pattern :

 class MyRunnable implements Runnable { private final MyListener l; private volatile boolean exit; int num; public MyRunnable(MyListener l) { this.l = l; exit = false; } @Override public void run() { while(!exit) { System.out.println(t.currentThread().getName()+": "+num); l.check(num++); try { t.sleep(200); } catch(InterruptedException e) {} } } public void stop() { exit = true; } } class MyListener { private final threshold; public MyListener(int x) { this.threshold = x; } public void check(MyRunnable r, int num) { if (num >= threshold) r.stop(); } } 

and your main method will look something like this:

 public static void main(String[] args) { MyListener l = new MyListener(1); Runnable r = new MyRunnable(l); new Thread(r).start(); } 
0
source

Source: https://habr.com/ru/post/1262933/


All Articles