I'm new to multithreaded; is this the right way to go about starting a thread?
if(!sesThread.isAlive()) {
try {
sesThread.start();
}catch(IllegalThreadStateException e) { System.out.println("y u start");}
}
premise: caller processes bytearrays and push it to a queue. session thread is to deque and further process them until queue is empty and hence sessions's run() returns
problem: im getting alot of exceptions getting thrown and even so my session thread for some reason has its run() being called twice!
i.e. (start > start > end > end) NOT (start > end > start > end)
Is there some way to synchronize or ensure this "lazy instantiation"-ish mechanism call start only once?
ps. im making a multithreaded UDP socket server aimed at delivery speed, so itd be great to have minimal delay and not some thread.sleep() prior to isAlive()
No you should not use this mechanism.
Your consumer thread should not terminate just because the queue is empty. Threads are expensive to start. You should use a BlockingQueue and have your consumer thread block when the queue is empty.
public class TwoThreads {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test");
new TwoThreads().test();
}
// The end of the list.
private static final Integer End = -1;
static class Producer implements Runnable {
final BlockingQueue<Integer> queue;
public Producer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
queue.add(i);
Thread.sleep(1);
}
// Finish the queue.
queue.add(End);
} catch (InterruptedException ex) {
// Just exit.
}
}
}
static class Consumer implements Runnable {
final BlockingQueue<Integer> queue;
public Consumer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
boolean ended = false;
while (!ended) {
Integer i = queue.take();
ended = i == End;
System.out.println(i);
}
}
}
public void test() throws InterruptedException {
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
// Start it all going.
pt.start();
ct.start();
// Wait for it to finish.
pt.join();
ct.join();
}
}
A Thread which is not started is just another object. Calling isAlive() makes no sense. A running thread can be alive, a thread object can't.
Is there some way to synchronize or ensure this "lazy
instantiation"-ish mechanism call start only once?
A thread can be started only once. Calling start() again will lead to IllegalThreadStateException
Related
Problem: I have collection of threads start in a loop parallelly. After exiting anyone of thread first ,all other running threads must be terminated. This is what I tried but it doesn't work. Any help is appreciated.
public class ThreadsMain {
public static void main(String[] args) {
int SIZE = 3;
Thread t[] = new Thread[SIZE];
for (int i = 0; i < SIZE; i++) {
myThreads th = new myThreads();
t[i] = new Thread(th);
t[i].start();
}
}
}
Here is one way to do it, with a synchronizer implemented with intrinsic locks, and using interruption to cancel the unfinished tasks. The data structure makes a consumer thread block until a producer has submitted a result, then it cancels the other worker threads.
This is a toy example, see the link at the end for the real-world way to do this.
First, here's a threadsafe data structure that accepts results, it allows threads to register as listeners and interrupts them once it has a result submitted to it:
class MyQueue<T> {
private java.util.List<T> results = new java.util.ArrayList<T>();
private java.util.List<Thread> listeners = new java.util.ArrayList<Thread>();
public synchronized void put(T o) {
results.add(o);
notifyAll();
for (Thread listener : listeners) {
listener.interrupt();
}
}
public synchronized T take() throws InterruptedException {
while (results.size() == 0) {
wait();
}
return results.remove(0);
}
public synchronized void addListener(Thread t) {
listeners.add(t);
}
}
(I don't like having this class know so much about the listeners but I don't want to overthink a toy example either.)
The wait method releases the lock and makes the calling thread go dormant until a notification occurs (or it can just stop waiting arbitrarily). It uses the size property of the results list to know when a result has been submitted. It's not safe to assume that because a thread stopped waiting that you can infer something about the current state, once the thread reacquires the lock it needs to check what the current state actually is. For more about how wait works see this tutorial.
Here's a task that calculates a result (sleeping between iterations just so these threads can run for a while):
class FibTask implements Runnable {
private final MyQueue<BigInteger> queue;
private final int n;
private long sleepTime;
public FibTask(int n, long sleepTime, MyQueue<BigInteger> queue) {
this.n = n;
this.sleepTime = sleepTime;
this.queue = queue;
}
#Override public void run() {
BigInteger a = BigInteger.valueOf(0);
BigInteger b = BigInteger.valueOf(1);
int i = 0;
try {
while (!Thread.currentThread().isInterrupted() && i < n) {
i = i + 1;
BigInteger temp = a;
a = b;
b = a.add(temp);
Thread.sleep(sleepTime);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
if (!Thread.currentThread().isInterrupted()) {
queue.put(b);
}
}
}
Notice in the code above how the Runnable needs to be aware of attempts to interrupt it. Interruption is cooperative, the task is responsible for deciding when to detect interruption and for handling the termination process.
Also if a task involves IO then in some cases interruption doesn't work and you have to close the socket, see this article for more discussion of this.
Here's the main program that runs the threads and gets the result. The MyQueue class is already doing most of the work so this doesn't have to do much:
class Completion {
public static void main(String ... args) throws Exception {
MyQueue<BigInteger> queue = new MyQueue<BigInteger>();
Thread t1 = new Thread(new FibTask(10, 1000L, queue));
Thread t2 = new Thread(new FibTask(20, 10000L, queue));
Thread t3 = new Thread(new FibTask(25, 50000L, queue));
queue.addListener(t1);
queue.addListener(t2);
queue.addListener(t3);
t1.start();
t2.start();
t3.start();
System.out.println(queue.take());
}
}
Be aware this isn't a fair race because of how the threads' starts are staggered, later threads are at a disadvantage. Submitting tasks to an Executor that initializes a threadpool up front would make sure that the time to start a thread didn't cause a delay here.
For a better way that makes use of java.util.concurrent features like Executors and Futures, see the example given in the API documentation for ExecutorCompletionService.
A simple approach, use a synchronized class to handle the loop condition:
class ThreadHandler
{
static Object lock = new Object();
static boolean finished = false;
static void finishThreads()
{
synchronized(lock)
{
finished = true;
}
}
static boolean isFinished()
{
boolean result;
synchronized(lock)
{
result = finished;
}
return result;
}
}
And in your runnable
class myThreads implements Runnable
{
#Override
public void run()
{
while(!ThreadHandler.isFinished())
{
}
}
}
I have started learning threads and tried Producer consumer problem in Java using concurrent package introduced in JDK 5.0 I have written the following code:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
class Producer implements Runnable {
private final BlockingQueue<Integer> objqueue;
Producer(BlockingQueue<Integer> obj) {
objqueue = obj;
}
#Override
public void run() {
int i = 0;
while (i < 10) {
try {
System.out.println("Put : " + i);
objqueue.put(i);
} catch (InterruptedException e) {
}
i++;
}
}
}
class Consumer implements Runnable {
private final BlockingQueue<Integer> objqueue;
Consumer(BlockingQueue<Integer> obj) {
objqueue = obj;
}
#Override
public void run() {
while (true) {
try {
System.out.println("Got : " + objqueue.take());
} catch (InterruptedException e) {
}
}
}
}
public class PCMain {
public static void main(String[] args) {
// create shared object
BlockingQueue<Integer> obj = new LinkedBlockingQueue<Integer>();
Thread prod = new Thread(new Producer(obj));
Thread cons = new Thread(new Consumer(obj));
prod.start();
cons.start();
}
}
The program is not terminating when the producer has produced up to 9 and consumer consumed up to 9. Should I remove the while loop which is true forever in Consumer.
How can I make it for more than one Producer and one Consumer?
Thanks.
Well you have two threads, one should stop once i == 10. The other thread is in an infinite loop though. You need to signal to the consuming thread that the application should end. Look at the Poison Pill as a way of telling the second thread to stop.
The program itself won't stop until that consuming thread completed.
Removing while loop will cause consumer will consume only 1 object given by producer.
Better to go Excecuter framework. It is having Thread Factory and Thread Pool.You can use to implement the same.
I think the easiest way to "fix" your code is to make the consumer a daemon thread.
Thread prod = new Thread(new Producer(obj));
Thread cons = new Thread(new Consumer(obj));
cons.setDaemon( true );
prod.start();
cons.start();
This really isn't a general solution, but a good trick to keep in mind when it's inconvenient to signal a thread to stop.
i want to pause thread which is writing messages in file by iterate message list. When message list is empty i want thread to stop and thread is resumed when message in a list.
I know stop,suspend (),resume methods is deprecated but if thread is continuously in background it consumes cpu. I did lots of googling but can't find proper answer. please any one help me out
Here is my code:
private Thread mFileWriterThread = new Thread() {
#Override
public synchronized void run() {
while (mIsRunning) {
synchronized (mMessageList) {
Iterator it = mMessageList.iterator();
while ((it.hasNext())) {
String message = (String) it.next();
writeToFile(fileOutputStream, message);
mMessageList.remove(message);
}
}
}
}
};
That's what a BlockingQueue exists for. It has a take() method that forces a thread to block until an Object is avalaible. Your problem can be solved with a simple producer-consumer design.
I'm pasting here a minimal snippet taken from the Oracle examples:
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
Of course Consumer an Producer have to share the queue somehow (just passing it to the constructor as shown in the example will work fine).
You want to use wait() to make the thread block*. And then call notify() to wake up the thread again. Google for "java wait notify" will give you a tutorial.
*Block here mean wait without using any resources, until an other thread wake it up.
I am confused with concurrency - i am trying to stop the consumer thread from running if the producer is shutdown but am having issues if the consumer is blocked on take(). I have tried adding a posion pill, interruptung the current thread, using a boolean flag and still to no avail.
Please can someone help advise where I am going wrong. Thanks.
public class TestPoisonPill implements Runnable {
private BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1);
private volatile boolean stopped = false;
public void addToQueue(String event) throws InterruptedException{
System.out.println("in add to queue");
if(event != null){
try {
queue.put(event);
} catch (InterruptedException e) {
stopped = true;
queue.put("Poison");
System.out.println("Unable to add the event to the queue, order routing processing is stopped");
throw e;
}
}
}
#Override
public void run() {
while(!stopped){
try {
if(queue.size() > 0){
String string = queue.take();
System.out.println("taken " + string + "from the queue");
}else{
continue;
}
}
catch (InterruptedException e) {
stopped = true;
}
}
}
public boolean isStopped(){
return stopped;
}
protected BlockingQueue<String> getQueue() {
return queue;
}
protected void setBoolean(boolean b){
this.stopped = b;
}
public static void main(String[] args) throws InterruptedException{
ExecutorService exec = Executors.newSingleThreadExecutor();
final TestPoisonPill t = new TestPoisonPill();
exec.execute(t);
ExecutorService exec2 = Executors.newSingleThreadExecutor();
Runnable addTask = new Runnable() {
public void run() {
while (true) {
try {
t.addToQueue("hi");
Thread.sleep(100);
} catch (InterruptedException ex) {
System.out.println("add task interrupted ");
t.setBoolean(true);
break;
}
}
}
};
exec2.execute(addTask);
Thread.sleep(1000);
exec2.shutdownNow();
}
}
am confused with concurrency - i am trying to stop the consumer thread from running if the producer is shutdown but am having issues if the consumer is blocked on take()
If you problem is that you program is not stopping, I think you are missing an exec.shutdownNow() on your first ExecutorService. This will interrupt your first thread, if you change your loop to be something like:
while (!stopped && !Thread.currentThread().isInterrupted()) {
Without the interrupt flag check any interrupt will be not been seen by the thread. An interrupt is just a flag that is set on the thread. Certain methods (like Thread.sleep(...) and BlockingQueue.take()) throw InterruptedException when a thread is interrupted but your consumer is spinning and never calling take().
Really, the spin loop in the consumer is an extremely bad pattern. It should just call queue.take() and then either use the interrupt or have your producer actually submit a poisoned pill. Something like:
while (!Thread.currentThread().isInterrupted()) {
String string;
try {
string = queue.take();
} catch (InterruptedException e) {
break;
}
// here is where you could check for a poison pill
// something like: if (string == STOP_PILL) break;
System.out.println("taken " + string + "from the queue");
}
You don't really need the stopped flag if you are using interrupt appropriately.
You mention having tried a "poisoned pill". For others, a poisoned pill is when you put a specific "special" object on the queue which the consumer uses to know when to shutdown. Something like the following should work:
private static final String STOP_PILL = "__STOP_PLEASE!!__";
...
// the consumer removes from the queue
String string = queue.take();
// it tests to see if it a pill, == is better than .equals here
if (string == STOP_PILL) {
// the consumer should stop
break;
}
...
// to stop the consumer, the producer puts the pill into the queue
queue.put(STOP_PILL);
Lastly, you are using 2 ExecutorService instances when you could easily use one. I guess the point here is to interrupt only one of them but FYI. You can use a single Executors.newCachedThreadPool() which will create the number of threads you need.
You never shutdown your exec executor, only exec2, so the thread running your TestPoisonPill never gets interrupted.
I need a solution to properly stop the thread in Java.
I have IndexProcessorclass which implements the Runnable interface:
public class IndexProcessor implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(IndexProcessor.class);
#Override
public void run() {
boolean run = true;
while (run) {
try {
LOGGER.debug("Sleeping...");
Thread.sleep((long) 15000);
LOGGER.debug("Processing");
} catch (InterruptedException e) {
LOGGER.error("Exception", e);
run = false;
}
}
}
}
And I have ServletContextListener class which starts and stops the thread:
public class SearchEngineContextListener implements ServletContextListener {
private static final Logger LOGGER = LoggerFactory.getLogger(SearchEngineContextListener.class);
private Thread thread = null;
#Override
public void contextInitialized(ServletContextEvent event) {
thread = new Thread(new IndexProcessor());
LOGGER.debug("Starting thread: " + thread);
thread.start();
LOGGER.debug("Background process successfully started.");
}
#Override
public void contextDestroyed(ServletContextEvent event) {
LOGGER.debug("Stopping thread: " + thread);
if (thread != null) {
thread.interrupt();
LOGGER.debug("Thread successfully stopped.");
}
}
}
But when I shutdown tomcat, I get the exception in my IndexProcessor class:
2012-06-09 17:04:50,671 [Thread-3] ERROR IndexProcessor Exception
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at lt.ccl.searchengine.processor.IndexProcessor.run(IndexProcessor.java:22)
at java.lang.Thread.run(Unknown Source)
I am using JDK 1.6. So the question is:
How can I stop the thread and not throw any exceptions?
P.S. I do not want to use .stop(); method because it is deprecated.
Using Thread.interrupt() is a perfectly acceptable way of doing this. In fact, it's probably preferrable to a flag as suggested above. The reason being that if you're in an interruptable blocking call (like Thread.sleep or using java.nio Channel operations), you'll actually be able to break out of those right away.
If you use a flag, you have to wait for the blocking operation to finish and then you can check your flag. In some cases you have to do this anyway, such as using standard InputStream/OutputStream which are not interruptable.
In that case, when a thread is interrupted, it will not interrupt the IO, however, you can easily do this routinely in your code (and you should do this at strategic points where you can safely stop and cleanup)
if (Thread.currentThread().isInterrupted()) {
// cleanup and stop execution
// for example a break in a loop
}
Like I said, the main advantage to Thread.interrupt() is that you can immediately break out of interruptable calls, which you can't do with the flag approach.
In the IndexProcessor class you need a way of setting a flag which informs the thread that it will need to terminate, similar to the variable run that you have used just in the class scope.
When you wish to stop the thread, you set this flag and call join() on the thread and wait for it to finish.
Make sure that the flag is thread safe by using a volatile variable or by using getter and setter methods which are synchronised with the variable being used as the flag.
public class IndexProcessor implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(IndexProcessor.class);
private volatile boolean running = true;
public void terminate() {
running = false;
}
#Override
public void run() {
while (running) {
try {
LOGGER.debug("Sleeping...");
Thread.sleep((long) 15000);
LOGGER.debug("Processing");
} catch (InterruptedException e) {
LOGGER.error("Exception", e);
running = false;
}
}
}
}
Then in SearchEngineContextListener:
public class SearchEngineContextListener implements ServletContextListener {
private static final Logger LOGGER = LoggerFactory.getLogger(SearchEngineContextListener.class);
private Thread thread = null;
private IndexProcessor runnable = null;
#Override
public void contextInitialized(ServletContextEvent event) {
runnable = new IndexProcessor();
thread = new Thread(runnable);
LOGGER.debug("Starting thread: " + thread);
thread.start();
LOGGER.debug("Background process successfully started.");
}
#Override
public void contextDestroyed(ServletContextEvent event) {
LOGGER.debug("Stopping thread: " + thread);
if (thread != null) {
runnable.terminate();
thread.join();
LOGGER.debug("Thread successfully stopped.");
}
}
}
Simple answer:
You can stop a thread INTERNALLY in one of two common ways:
The run method hits a return subroutine.
Run method finishes, and returns implicitly.
You can also stop threads EXTERNALLY:
Call system.exit (this kills your entire process)
Call the thread object's interrupt() method *
See if the thread has an implemented method that sounds like it would work (like kill() or stop())
*: The expectation is that this is supposed to stop a thread. However, what the thread actually does when this happens is entirely up to what the developer wrote when they created the thread implementation.
A common pattern you see with run method implementations is a while(boolean){}, where the boolean is typically something named isRunning, it's a member variable of its thread class, it's volatile, and typically accessible by other threads by a setter method of sorts, e.g. kill() { isRunnable=false; }. These subroutines are nice because they allow the thread to release any resources it holds before terminating.
You should always end threads by checking a flag in the run() loop (if any).
Your thread should look like this:
public class IndexProcessor implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(IndexProcessor.class);
private volatile boolean execute;
#Override
public void run() {
this.execute = true;
while (this.execute) {
try {
LOGGER.debug("Sleeping...");
Thread.sleep((long) 15000);
LOGGER.debug("Processing");
} catch (InterruptedException e) {
LOGGER.error("Exception", e);
this.execute = false;
}
}
}
public void stopExecuting() {
this.execute = false;
}
}
Then you can end the thread by calling thread.stopExecuting(). That way the thread is ended clean, but this takes up to 15 seconds (due to your sleep).
You can still call thread.interrupt() if it's really urgent - but the prefered way should always be checking the flag.
To avoid waiting for 15 seconds, you can split up the sleep like this:
...
try {
LOGGER.debug("Sleeping...");
for (int i = 0; (i < 150) && this.execute; i++) {
Thread.sleep((long) 100);
}
LOGGER.debug("Processing");
} catch (InterruptedException e) {
...
Typically, a thread is terminated when it's interrupted. So, why not use the native boolean? Try isInterrupted():
Thread t = new Thread(new Runnable(){
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
// do stuff
}
}});
t.start();
// Sleep a second, and then interrupt
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
t.interrupt();
ref- How can I kill a thread? without using stop();
For synchronizing threads I prefer using CountDownLatch which helps threads to wait until the process being performed complete. In this case, the worker class is set up with a CountDownLatch instance with a given count. A call to await method will block until the current count reaches zero due to invocations of the countDown method or the timeout set is reached. This approach allows interrupting a thread instantly without having to wait for the specified waiting time to elapse:
public class IndexProcessor implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(IndexProcessor.class);
private final CountDownLatch countdownlatch;
public IndexProcessor(CountDownLatch countdownlatch) {
this.countdownlatch = countdownlatch;
}
public void run() {
try {
while (!countdownlatch.await(15000, TimeUnit.MILLISECONDS)) {
LOGGER.debug("Processing...");
}
} catch (InterruptedException e) {
LOGGER.error("Exception", e);
run = false;
}
}
}
When you want to finish execution of the other thread, execute countDown on the CountDownLatch and join the thread to the main thread:
public class SearchEngineContextListener implements ServletContextListener {
private static final Logger LOGGER = LoggerFactory.getLogger(SearchEngineContextListener.class);
private Thread thread = null;
private IndexProcessor runnable = null;
private CountDownLatch countdownLatch = null;
#Override
public void contextInitialized(ServletContextEvent event) {
countdownLatch = new CountDownLatch(1);
Thread thread = new Thread(new IndexProcessor(countdownLatch));
LOGGER.debug("Starting thread: " + thread);
thread.start();
LOGGER.debug("Background process successfully started.");
}
#Override
public void contextDestroyed(ServletContextEvent event) {
LOGGER.debug("Stopping thread: " + thread);
if (countdownLatch != null)
{
countdownLatch.countDown();
}
if (thread != null) {
try {
thread.join();
} catch (InterruptedException e) {
LOGGER.error("Exception", e);
}
LOGGER.debug("Thread successfully stopped.");
}
}
}
Some supplementary info.
Both flag and interrupt are suggested in the Java doc.
https://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
For a thread that waits for long periods (e.g., for input), use Thread.interrupt
public void stop() {
Thread moribund = waiter;
waiter = null;
moribund.interrupt();
}
I didn't get the interrupt to work in Android, so I used this method, works perfectly:
boolean shouldCheckUpdates = true;
private void startupCheckForUpdatesEveryFewSeconds() {
threadCheckChat = new Thread(new CheckUpdates());
threadCheckChat.start();
}
private class CheckUpdates implements Runnable{
public void run() {
while (shouldCheckUpdates){
System.out.println("Do your thing here");
}
}
}
public void stop(){
shouldCheckUpdates = false;
}
Brian Goetz in his book suggests to use Thread.currentThread().isInterrupted() flag and interrupt() method for cancellation.
Blocking library methods like sleep() and wait() try to detect when a thread has been interrupted and return early. They respond to interruption by clearing the interrupted status and throwing InterruptedException, indicating that the blocking operation completed early due to interruption.
The JVM makes no guarantees on how quickly a blocking method will detect interruption, but in practice this happens reasonably quickly.
class PrimeProducer extends Thread {
private final BlockingQueue<BigInteger> queue;
PrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
public void run() {
try {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted()) {
queue.put(p = p.nextProbablePrime()); // blocking operation
}
} catch (InterruptedException consumed) {
// allow thread to exit
}
// any code here will still be executed
}
public void cancel() {
interrupt();
}
}
If you put any code after catch block, it will still be executed as we swallow InterruptedException to exit from run() gracefully.
Just a couple words on how interrupt() works.
If interrupt is called on non-blocked thread, interrupt() will not cause InterruptedException inside run() but will just change flag isInterrupted to true and thread will continue its work until it reaches Thread.currentThread().isInterrupted() check and exit from run().
If interrupt is called on blocked thread (sleep() or wait()was called, in our case it's put() that might block a thread) then isInterrupted will be set to false and InterruptedException will be thrown inside put().