How can this loop come out?

So, I checked the test, and the results do not make any sense to me. Consider the following code:

ThreadStuffCounter counter_1 = new ThreadStuffCounter(1); while(counter_1.doProceed) { Thread.sleep(500); Thread thread = new Thread(counter_1); thread.start(); } 

With Runnable as follows:

 package test; public class ThreadStuffCounter implements Runnable { public volatile boolean doProceed = true; private int id = -1; public volatile int i = -1; public ThreadStuffCounter(int id) { this.id = id; } @Override public void run() { for (i = 0; i < 10; i++) { System.out.println("i = " + i + " in runnable id = " + id); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } doProceed = false; } } 

Only one counter instance is shared between threads. It will take less time to start another thread, but even one step that needs to be done in counter.doProceed should, as I understand it, never be set to false, and the loop should go on indefinitely until I get an exception from memory and I can no longer start flows.

How can I get out of a loop?

EDIT: modified code to make sure the answer is below.

 package test; public class ThreadStuffCounter implements Runnable{ public volatile boolean doProceed = true; private int id = -1; volatile int i = -1; public ThreadStuffCounter(int id){ this.id = id; } @Override public void run() { i = 0; while (i < 10){ System.out.println("i = " + i + " in runnable id = " + id + "; from thead id = " + Thread.currentThread().getId()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } i++; } ThreadStuff.doProceed = false; } 

}

AND

 package test; public class ThreadStuff { public static volatile boolean doProceed = true; public static void main (String[] args) throws InterruptedException{ ThreadStuffCounter counter_1 = new ThreadStuffCounter(1); while(doProceed){ Thread.sleep(500); Thread thread = new Thread(counter_1); thread.start(); } } 

}

In addition, it appears more than n threads if you are working for i <n. You need a lot, so n threads increase at the same time.

+6
source share
1 answer

If at least one of the threads executes a for loop, and the value of i greater than or equal to 10, then the doProceed variable will be false (yes, this can happen), and since it is volatile this will stop the execution of the while , which creates and starts new threads. Then, down to all threads, you just need to end the execution of the for loop code, and then complete their execution. This is similar to the fact that the start time of a new thread in your environment is slower than the time when the current thread completes its execution. Also note that multiple threads may increase the value of i , which will speed up the execution of the for loop.

It is likely that if you focus on a higher value (not tested), then this can cause an endless loop, and the application will break when there are not enough resources to create and start new threads.


After some tests using the limit of 10, 50 and 1000. I noticed that when you have a larger value, since many threads are created, all of them simultaneously increase the value of i and i slowly starts to approach the limit value set in the for loop. Description of the current environment:

  • OS: Windows 7 Professional 64 bit
  • Processor: Intel (R) Core (TM) i5-2520M CPU @ 2.50 GHz (4 processors), ~ 2.5 GHz
  • Ram: 8192 MB
+3
source

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


All Articles