I tried using a volatile boolean to act as a flag to stop/start/restart the action in the thread, however it does not work. It just keeps on going forever and never terminates. Any help on how to properly do this or why my code does not work will be greatly appreciated. Thanks in advance.
public class thread {
public static int i = 0;
private static Thread print = null;
private static printThread runnable = null;
public static void main(String[] args) {
runnable = new printThread();
print = new Thread (runnable);
print.start();
System.out.println("Starting");
runnable.begin();
if(i > 5)
{
runnable.terminate();
}
i = 10;
runnable.begin();
if(i > 15)
{
runnable.terminate();
}
}
public static final void print()
{
System.out.println(i);
i++;
}
public static final class printThread implements Runnable {
private volatile boolean running = false;
public void terminate() {
running = false;
}
public void begin() {
running = true;
}
public boolean isRunning() {
return running;
}
public void run() {
while(true)
{
if(running)
{
print();
}
else
{
}
}
}
}
}
In your code while loop execution never ends. You could introduce 2 states: terminated and waiting to simulate threads start/pause/restart/stop. However, even if you pause the Thread it will be running, just different branch of code will be executed inside while loop.
Please, see the code snippet below
public static final class printThread implements Runnable {
private volatile boolean waiting = false;
private volatile boolean terminated = false;
public void terminate() {
terminated = true;
}
public void pause() {
waiting = true;
}
public void restart() {
waiting = false;
}
public void run() {
while(!terminated) {
if(waiting) {
//the thread is paused
} else {
//the thread is running
}
}
}
}
however it does not work. It just keeps on going forever and never terminates.
In your run() method of your thread, you aren't watching for the value of your volatile boolean running field. It probably should be something like:
public void run() {
while(!running) {
print();
// you might want a short Thread.sleep(10); here to stop the spinning
}
}
However, as #Anton points out, once your thread terminates, it can't be restarted without some other flag. See his answer.
Also, you are sharing i between the main thread and the your printing thread. That also needs to be volatile so it can be properly shared. Since you are incrementing it in multiple threads, you should use an AtomicInteger for that.
public static AtomicInteger i = new AtomicInteger();
...
if (i.get() > 5) ...
...
i.set(10);
...
i.incrementAndGet();
Couple of other comments:
Be careful of static fields. print and runnable should be defined only inside of the main(...) method to restrict access.
Classes should begin with an uppercase letter so it should be PrintThread.
Actually, because PrintThread isn't a thread, it should be PrintRunnable or maybe even better, Printer.
Related
I was going through one of the tutorials on memory model of Java and came across this concept of field visibility which happens in multi-threaded programming. I tried to simulate the same using the below code, however , I see in each thread, the latest value is being reflected (in ReaderThread).
The below is the complete program.
Edit
After some suggestion to use while(somevariable), I incorporated, but still getting the same behaviour. I removed sysout on reading the x
FieldVisibility.java
package com.example.threads.fieldvisibility;
public class FieldVisibility {
private int x;
private boolean condition;
public FieldVisibility() {
condition = true;
}
public void reader() {
System.out.println("x in reader() is " + x);
}
public void writer() {
x++;
}
public boolean getCondition() {
return condition;
}
public void setCondition(boolean condition) {
this.condition = condition;
}
}
ReaderThread.java
package com.example.threads.fieldvisibility;
public class ReaderThread extends Thread {
private FieldVisibility fv;
public ReaderThread(FieldVisibility fv) {
this.fv = fv;
}
#Override
public void run() {
while (fv.getCondition()) {
System.out.println("It mean condition is true, which was set initially");
}
for (;;) {
}
}
}
WriterThread.java
package com.example.threads.fieldvisibility;
public class WriterThread extends Thread {
private FieldVisibility fv;
public WriterThread(FieldVisibility fv) {
this.fv = fv;
}
#Override
public void run() {
fv.setCondition(false);
for (;;) {
fv.writer();
}
}
}
MainApp.java
package com.example.threads.fieldvisibility.main;
import com.example.threads.fieldvisibility.FieldVisibility;
import com.example.threads.fieldvisibility.ReaderThread;
import com.example.threads.fieldvisibility.WriterThread;
public class MainApp {
public static void main(String[] args) throws InterruptedException {
FieldVisibility fv = new FieldVisibility();
ReaderThread rt = new ReaderThread(fv);
WriterThread wt = new WriterThread(fv);
wt.start();
rt.start();
Thread.sleep(999999999L);
}
}
Edit
I added a new variable condition in FieldVisibility, whose default values is true. Next, I set its value to false in WriterThread, however, the same value (false) is still propagated to ReaderThread, so I still am not able to simulate it.
Original
I expected that at some time ReaderThread won't be able to "see" the latest value of variable x, but I saw every time I run it, it gave same results. I even run in debug mode, suspended ReaderThread while running WriterThread continuously. But that also didn't prevent ReaderThread to have latest values. I expected that I need to declare variable x as volatile in order for ReaderThread to read latest values of x.
How can I simulate the field visibility concept, or what changes I need to do for this?
Your example doesn't work because System.out.println() uses a shared resource (System.out), so it will synchronize with other uses of the same resource.
Therefore you will never* see a result where one thread uses the old value of the other. (*in theory it is possible for the reader to read x between x++ and the corresponding System.out.println()
Here is an example where a old value is used:
public class ThreadVisibility implements Runnable {
private boolean stop = false;
#Override
public void run() {
while (!stop);
}
public static void main(String[] args) throws InterruptedException {
ThreadVisibility test = new ThreadVisibility();
Thread t = new Thread(test);
t.setDaemon(true);
System.out.println("Starting Thread");
t.start();
Thread.sleep(1000);
System.out.println("Stopping Thread");
test.stop = true;
t.join(1000);
System.out.println("Thread State: " + t.getState());
}
}
If you run this code, it will display that the thread is still running at the end. Without the t.setDaemon(true), the VM would wait for the Thread to finish, which would never happen.
If you comment out the Thread.sleep, then the new Thread may terminate (at least it did in my tests), but it is not guaranteed to.
The right fix for this problem is to declare stop volatile.
Or add a memory barrier.
Let's say that I have an algorithm that does something for a given parameter. If the algorithm runs longer than 100 miliseconds then I want to stop it and try again for a different parameter.
I posted below the code that would test the algorithm for a random parameter... and how I think the code might look like:
public class StopThread {
private Lock lock = new ReentrantLock();
public static void main(String... args) {
System.out.println("Starting threads...");
(new StopThread()).startThreads(100);
}
private void startThreads(int nrOfThreads) {
for (int i = 0; i < nrOfThreads; i++) {
startThread(i, (long) (Math.random() * 10000000000l));
System.out.println("Started thread number " + (i + 1));
}
}
private void startThread(final int number, final long load) {
Thread workerThread = new Thread() {
#Override
public void run() {
try {
lock.lock();
doAlgorithmWork(load);
} finally {
System.out.println("Thread " + (number + 1) + " finished...");
lock.unlock();
}
}
};
Thread timerThread = new Thread() {
#Override
public void run() {
try {
sleep(100);
} catch (InterruptedException e) {
}
}
};
workerThread.start();
timerThread.start();
do {
if (!workerThread.isAlive() || !timerThread.isAlive()) {
workerThread.stop();
timerThread.stop();
}
} while (!workerThread.isAlive() && !timerThread.isAlive());
}
protected void doAlgorithmWork(long load) {
while (load-- > 0) {
}
}
}
I feel like this question should already have an answer, but what I found until now seemed complicated and I didn't know how to use it. I'm not that knowledgeable with threads and I would appreciate if you could post some code.
A very simple solution would look like this:
private void startThreads(int nrOfThreads) {
for (int i = 0; i < nrOfThreads; i++) {
Thread worker = new Thread() {
#Override
public void run() {
doAlgorithmWork((long) (Math.random() * 10000000000l));
}
}
worker.start();
worker.join(100); //block until either the thread is done, or 100ms passed
if (worker.isAlive()) worker.stop(); //if thread is still alive, stop it
}
}
This will achieve your goal, but suffers from a number of "drawbacks"
It is single threaded (that is, all calls to doAlgorithm execute one after another, instead of in parallel, so you are only using a single core of your machine);
It uses the discouraged Thread.stop() method. A preferred approach is to instead have a "stop" flag which is set to true (in place of the stop() call), and which is also constantly checked for in doAlgorith;
It creates a new thread for each doAlgorithm call (instead of reusing a single thread), which is "wasteful", but for your case probably has little practical implications
UPDATE:
In order to avoid the deprecated stop() call, you will need to add a flag to your worker thread, creating a separate class like this:
public class Worker implements Runnable {
private volatile boolean stopped = false;
public void stop() {
stopped = true;
}
#Override
public void run() {
doAlgorithmWork((long) (Math.random() * 10000000000l));
}
private void doAlgorithmWork(long load) {
while (!stopped && load-- > 0) {
//calculation
}
}
}
Then your runner looks like this:
private void startThreads(int nrOfThreads) {
for (int i = 0; i < nrOfThreads; i++) {
Thread worker = new Thread(new Worker());
worker.start();
worker.join(100); //block until either the thread is done, or 100ms passed
if (worker.isAlive()) worker.stop(); //if thread is still alive, stop it
}
}
You could also create a constructor for Worker which accepts the load value (instead of having it generated inside the Worker itself).
Note that if the calculation inside doAlgorithm() is too time-consuming, the thread may run for more than 100ms (since it always completes each calculation within the loop). If this is an issue, then your alternative is to interrupt the thread instead (calling worker.interrupt() will cause an InterruptedException to be thrown within the run() method).
I have a class which processes something. I'm trying to run a number of instances of this class in parallel.
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping. So I'd like to know if I'm doing something wrong?
This is the structure of the class:
public class TaskRunner implements Runnable {
private boolean isRunning = false;
public void run() {
while(true) {
while (! running) {
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
process();
}
}
public void go() {
isRunning = true;
}
public void stop() {
isRunning = false;
}
private void process() {
//Do some number crunching and processing here
}
}
Here's how these are being run / managed:
public class TaskManager {
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager() {
for (int i = 0; i < 10; i++) {
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
}
public void startAll() {
for (TaskRunner r : runners) {
r.go();
}
}
}
Indeed, you are not "doing it right." If you want to create a multi-threaded Java application, the place to start is with the java.util.concurrent package.
It appears from your code that you want to run ten tasks in parallel. I assume that after "number crunching and processing," you'll want to aggregate the results and do something with them in the main thread. For this, the invokeAll() method of ExecutorService works well.
First, implement Callable to do the work you show in your process() method.
final class YourTask implements Callable<YourResults> {
private final YourInput input;
YourTask(YourInput input) {
this.input = input;
}
#Override
public YourResults call()
throws Exception
{
/* Do some number crunching and processing here. */
return new YourResults(...);
}
}
Then create your tasks and run them. This would take the place of your main() method:
Collection<Callable<YourResults>> tasks = new List<>(inputs.size());
for (YourInput i : inputs)
tasks.add(new YourTask(i));
ExecutorService workers = Executors.newFixedThreadPool(10);
/* The next call blocks while the worker threads complete all tasks. */
List<Future<YourResult>> results = workers.invokeAll(tasks);
workers.shutdown();
for (Future<YourResult> f : results) {
YourResult r = f.get();
/* Do whatever it is you do with the results. */
...
}
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
So my first comment is that you should make isRunning be volatile since it is being shared between threads. If the threads are not starting when it goes to true (or seem to be delayed in starting) then I suspect that's your problem. volatile provides memory synchronization between the threads so the thread that calls go() and makes a change to isRunning will be seen immediately by the thread waiting for the change.
Instead of spinning like this, I would use wait/notify:
// this synchronizes on the instance of `TaskRunner`
synchronized (this) {
// always do your wait in a while loop to protect against spurious wakeups
while (!isRunning && !Thread.currentThread().isInterrupted()) {
try {
// wait until the notify is called on this object
this.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
Then in the go() method you should do the following. stop() would be similar.
public void go() {
synchronized (this) {
isRunning = true;
this.notifyAll();
}
}
Notice that you should handle thread interrupts carefully. Test for isInterrupted() in the while running loop and re-interrupt a thread when InterruptedException is thrown is always a good pattern.
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping.
So although the threads are mostly sleeping, they are still each looping 1000 times a second because of your Thread.sleep(1). If you increased the time sleeping (after making isRunning be volatile) they would loop less but the right mechanism is to use the wait/notify to signal the thread.
Awful solution, terrible. first I highly recommend you start reading some tutorial like [this]
Second, if threads should wait for a signal to go for some job, so why just don't you wait them!!!!!, something like this
import java.util.ArrayList;
public class TaskManager
{
//////////////////////
public volatile static Signal wait=new Signal();
//////////////////////
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager()
{
for (int i = 0; i < 10; i++)
{
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
try {
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
pauseAll();
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
haltAll();System.out.println("DONE!");
}catch(Exception ex){}
}
public void startAll()
{
synchronized(wait){
wait.setRun(true);;
wait.notifyAll();
}
}
public void pauseAll(){
wait.setRun(false);
}
public void haltAll(){
for(TaskRunner tx:runners){tx.halt();}
}
public static void main(String[] args) {
new TaskManager();
}
}
class TaskRunner implements Runnable
{
private Thread thisThread;
private volatile boolean run=true;
public void run()
{
thisThread=Thread.currentThread();
while(run){
if(!TaskManager.wait.isRun()){
synchronized(TaskManager.wait)
{
if(!TaskManager.wait.isRun()){
System.out.println("Wait!...");
try
{
TaskManager.wait.wait();
}
catch (Exception e)
{
e.printStackTrace();
break;
}
}
}}
process();
}
}
private double r=Math.random();
private void process(){System.out.println(r);try {
Thread.sleep(10);
} catch (Exception e) {
// TODO: handle exception
}}
public void halt(){run=false;thisThread.interrupt();}
}
class Signal{
private boolean run=false;
public boolean isRun() {
return run;
}
public void setRun(boolean run) {
this.run = run;
}
}
in above sample, all runners works till the Signal run boolean is true, and simple TaskManager class set tit as false for every time it needs to pause the threads. and about the halt, it just set the shutdown(run) flag to false, and also interrupt the thread because of if thread is in wait state.
I hope I could prove your solution is like dream-on story, and also could explained enough about my solution.
have a good parallel application :)
Essentially, what I want to do is start all my threads, pause them all, then resume them all, using the multithreading approach. I am just looking for a simple solution to this. I'm not sure if I have to use a timer or what. Right now when I run it, the threads are like being executed in random order (I guess the PC is just randomly picking which ones it wants to run at a certain time).
class ChoppingThread extends Thread
{
public void run()
{
for(int j=40;j!=0;j-=10)
System.out.println("Chopping vegetables...("+j+" seconds left)");
}
}
class MixingThread extends Thread
{
public void run()
{
for(int k=60;k!=0;k-=10)
System.out.println("Mixing sauces...("+k+" seconds left)");
}
}
class TenderizingThread extends Thread
{
public void run()
{
for(int j=50;j!=0;j-=10)
System.out.println("Tenderizing meat...("+j+" seconds left)");
}
}
class MultiThreadTasking
{
public static void main (String [] args)
{
ChoppingThread ct = new ChoppingThread();
MixingThread mt = new MixingThread();
TenderizingThread tt = new TenderizingThread();
System.out.println("\nWelcome to the busy kitchen.");
//putting threads into ready state
ct.start();
mt.start();
tt.start();
}
}
There are probably other ways to achieve the same result, but this is the simplest I can come up with off the top of my head (I know, sad isn't it)...
Basically, this is a special Runnable with some additional management functionality.
This basically contains a state flag that indicates the state of the task and a monitor lock
public class ThreadFun {
public static void main(String[] args) {
MyTask task = new MyTask();
Thread thread = new Thread(task);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
task.pauseTask();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
task.resumeTask();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
task.stopTask();
}
public enum TaskState {
Running,
Stopped,
Paused
}
public static class MyTask implements Runnable {
private static final Object PAUSED_LOCK = new Object();
private volatile TaskState state = TaskState.Running;
public void pauseTask() {
if (state == TaskState.Running) {
System.out.println("Paused...");
state = TaskState.Paused;
}
}
public void resumeTask() {
if (state == TaskState.Paused) {
state = TaskState.Running;
synchronized (PAUSED_LOCK) {
PAUSED_LOCK.notifyAll();
}
System.out.println("Resumed...");
}
}
public void stopTask() {
if (state == TaskState.Running || state == TaskState.Paused) {
state = TaskState.Stopped;
System.out.println("Stopped...");
}
}
public boolean isStopped() {
return state == TaskState.Stopped;
}
public boolean isPaused() {
return state == TaskState.Paused;
}
protected void doPause() {
synchronized (PAUSED_LOCK) {
while (isPaused()) {
try {
PAUSED_LOCK.wait();
} catch (InterruptedException ex) {
}
}
}
}
#Override
public void run() {
int index = 0;
while (!isStopped() && index < 1000) {
try {
Thread.sleep(25);
} catch (InterruptedException ex) {
}
doPause();
index++;
System.out.println(index);
}
stopTask(); // Make sure the task is marked as begin stopped ;)
}
}
}
The main criteria is you will need to pool isStopped and doPause at appropriate points to ensure that they are begin implemented as required...
To coordinate them use a CyclicBarrier.
To launch them all at the same time use a CountDownLatch.
Google the two classes above for many examples and explanations.
To fully understand what is happening read the Java Concurrency In Practice book.
I believe you can accomplish this by using Object.wait and Thread.interrupt.
Object.wait blocks until notify is called. So
private boolean paused;
private Object waitObject;
...
public void run() {
for ... {
if (this.paused) { this.waitObject.wait(); }
...
public void pause() { this.paused = true; }
public void resume() { this.paused = false; this.waitObject.notify(); }
Then you can call pause to pause the thread.
Thread.interrupt can help with stopping.
private boolean paused;
...
public void run() {
for ... {
// interrupted() is different from interrupt()!
if (this.iterrupted()) { break; }
...
To stop it, you would call interrupt() from another thread.
This is the basic idea, but there's a lot of details to worry about here. For example, wait can throw an InterruptedException you'll need to handle. Also, wait is not guaranteed to return only after a notify. It can return randomly. Here is a pair of tutorials:
Wait: http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
Interrupt: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
I made a sweet system update feature for this game I'm making here is the code:
public static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private static CountDownThread countDownThread;
public static boolean running = false;
private static short updateSeconds;
public static void start() {
System.out.println("starting");
running = true;
countDownThread = new CountDownThread();
scheduler.scheduleWithFixedDelay(countDownThread, 0, 1000, TimeUnit.MILLISECONDS);
}
public static void stop() {
System.out.println("Stoping");
scheduler.shutdown();
running = false;
updateSeconds = 0;
System.out.println("Stopped");
}
public static void refresh() {
for (Player p : Static.world.players){
if (p.ready()) {
if (updateSeconds > 0) {
ActionSender.sendSystemUpdate(p, updateSeconds+1);
} else {
ActionSender.sendSystemUpdate(p, updateSeconds);
}
}
}
}
public static short getUpdateSeconds() {
return updateSeconds;
}
public static void setUpdateSeconds(short updateSeconds) {
SystemUpdateHandler.updateSeconds = (short) (updateSeconds);
}
public static class CountDownThread implements Runnable {
#Override
public void run() {
System.out.println(updateSeconds);
updateSeconds--;
if (updateSeconds <= 0) {
Static.server.restart();
scheduler.shutdown();
running = false;
}
}
}
}
That's so, when the system update counter reaches 0, the server will restart its self. It works fine but here where the problem begins
case "update":
if (Short.parseShort(txtSystemUpdate.getText()) != 0) {
SystemUpdateHandler.setUpdateSeconds(Short.parseShort(txtSystemUpdate.getText()));
SystemUpdateHandler.refresh();
if (!SystemUpdateHandler.running) {
SystemUpdateHandler.start();
}
} else {
SystemUpdateHandler.stop();
for (Player p : Static.world.players){
if (p.ready()) {
ActionSender.sendSystemUpdate(p, 0);
}
}
}
break;
That is where I call it, basically if I enter a number higher than 0, the program works fine. But I want it so if I enter the number 0, the scheduler will stop running(to save memory) because it not needed unless I send a system update. Basically how do I stop the scheduler from running when I enter 0, but able to starts it back up when I enter a number > then 0(several times).
Once shutdown the ExecutorService can't be started again so move the creation of it from the variable declaration (and remove final) and do that in the start method instead:
//not static and not final, normal instance variable instead:
public ScheduledExecutorService scheduler;
...
//and create it in the start method isntead:
public static void start() {
System.out.println("starting");
scheduler = Executors.newSingleThreadScheduledExecutor();
...
When shutting down, you will get list of tasks submitted to the scheduler, and you can use this list to create new one. Scheduler can not be started once stopped - because thread pool is dead and all worker threads are dead as well.