#Component
class Type
{
#PostConstruct
private void postConstructor() {
Runnable threadAlpha = () -> {
while (true) {
workWithSomething();
try {
Thread.sleep(1000 * 60);
} catch (InterruptedException e) {
}
}
};
Runnable threadBeta = () -> {
while (true) {
workWithOtherthing();
try {
Thread.sleep(1000 * 3);
} catch (InterruptedException e) {
}
}
};
threadBeta.run();
threadAlpha.run();
}
}
With spring-framework, I am struggling with this piece of code, the problem is only one thread can actually started which call run() first, the other one seems freezing, If I switch the location to be like:
threadAlpha.run();
threadBeta.run();
Then threadBeta never started, why something happen like that?
Because you're not creating threads. Instead of that you're creating Runnable instances and then running their run method.
Instead do this:
new Thread(threadAlpha).start();
new Thread(threadBeta).start();
The Runnable run() executes in the current thread and hence the behavior. If you want to run in two separate threads use Thread and call start on those:
public class SpringMultipleThreads {
public static void main(String[] args) {
new SpringMultipleThreads().postConstructor();
}
private void postConstructor() {
Thread threadAlpha = new Thread(() -> {
while (true) {
System.out.println("1");
try {
Thread.sleep(1000 * 3);
} catch (InterruptedException e) {
}
}
});
Thread threadBeta = new Thread(() -> {
while (true) {
System.out.println("2");
try {
Thread.sleep(1000 * 3);
} catch (InterruptedException e) {
}
}
});
threadBeta.start();
threadAlpha.start();
}
}
When you call threadAlpha.run() and threadBeta.run() you are executing it in the current thread. For simple execution in new thread you can use:
Thread t1 = new Thread(threadAlpha);
t1.start();
Thread t2 = new Thread(threadBeta);
t2.start();
SimpleThreads tutorial from Oracle.
When you are calling threadBeta.run() or threadAlpha.run() you are calling a method which has an infinite loop. You are not creating a thread. That's why threadAlpha.run() isn't executing even as threadBeta.run() is in an infinite loop. Instead you can do this:
new Thread(threadBeta).start();
new Thread(threadAlpha).start();
Related
Below is the consumer producer problem code, but the code is not working as expected. Here the consumer and producer are supposed to be just producing and consuming one object.
public class ProducerConsumer {
private static LinkedList<Integer> linkedList = new LinkedList<>();
public static void main(String a[]) throws InterruptedException {
Thread producer = new Thread(new Runnable() {
#Override
public void run() {
synchronized(this) {
while (linkedList.size() == 1) {
try {
wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced");
linkedList.add(1);
notify();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread consume = new Thread(new Runnable() {
#Override
public void run() {
// produce
synchronized(this) {
while (linkedList.isEmpty()) {
try {
wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumed");
linkedList.removeFirst();
notify();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
producer.start();
consume.start();
producer.join();
consume.join();
}
}
We get the output as : Produced
And the program hangs.
Please help with possible solutions/ explanations
Use a shared lock. In the posted code each Runnable is using itself as a lock so no actual locking takes place.
When a thread waits, another thread needs to call notify on the same lock in order to wake up the waiting thread. We know from your logging that the Producer thread does its thing, but since the notify acts on a lock that is not the same as the one the Consumer is using, the consumer thread never wakes up.
Changing the code to use a shared lock works:
import java.util.*;
public class ProducerConsumer { private static LinkedList linkedList = new LinkedList();
public static void main(String a[]) throws InterruptedException {
final Object lock = new Object();
Thread producer = new Thread(new Runnable() {
#Override
public void run() {
synchronized (lock) {
while (linkedList.size() ==1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced");
linkedList.add(1);
lock.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread consume = new Thread(new Runnable() {
#Override
public void run() {
// produce
synchronized (lock) {
while (linkedList.isEmpty()) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumed");
linkedList.removeFirst();
lock.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
producer.start();
consume.start();
producer.join();
consume.join();
}
}
Output for this is:
c:\example>java ProducerConsumer
Produced
Consumed
which I think is what you're expecting.
Btw see this other answer I wrote for a dirt-simple implementation of a queue; you are better off protecting the shared data structure than putting the code in the threads accessing the data structure, especially look at how much easier the code is to write.
Concurrency means that you can not know before runtime which Thread will end first. So you can not know which of the Consumer and Producer is launched, executed or finished first.
To help you, you can use a cyclic barrier https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html or applying the Fork/Join Framework https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
Your synchronized blocs just say : only one Thread at a time can execute this part of code, not execute the first and the second after.
An example of how CyclicBarrier works :
service = Executors.newFixedThreadPool(numThreadsTotal);
CyclicBarrier c = new CyclicBarrier(numThreadsToWait);
runProducer();
c.await();
runConsumer();
It will wait until the there is as much Threads as numThreadsToWait that have execute the runProducer to execute the runConsumer().
Perhaps using a Thread Pool with a size of 1 could help you, but you will loose the benefits of concurrency.
I think best what you can do, is use BlockingQueue.
I'm trying to come with a solution for a thread to pause and resume exactly where it was left off.
So here's a sample code emulating my problem: 2 threads are running in the background: taskThread & busyThread. When busyThread is in system is busy area, taskThread must alt/pause immediately and resume exactly where it was left off. Example, if taskThread was paused at task C (finished) it should resume at D.
I tried to use wait, notify on taskThread but without success.
public class Test
{
private Thread taskThread;
private Thread busyThread;
public static void main(String args[]) throws Exception
{
Test t = new Test();
t.runTaskThread();
t.runBusyThread();
}
public void runTaskThread()
{
taskThread = new Thread(new Runnable(){
#Override
public void run()
{
for (int x=0; x<100; x++)
{
try
{
System.out.println("I'm doing task A for process #"+x);
Thread.sleep(1000);
System.out.println("I'm doing task B for process #"+x);
Thread.sleep(200);
System.out.println("I'm doing task C for process #"+x);
Thread.sleep(300);
System.out.println("I'm doing task D for process #"+x);
Thread.sleep(800);
System.out.println("\n\n");
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}});
taskThread.start();
}
public void runBusyThread()
{
busyThread = new Thread(new Runnable(){
#Override
public void run()
{
while (true)
{
Random rand = new Random();
int randomNum = rand.nextInt(1000);
if (randomNum<400)
{
System.out.println("Wait...system is busy!!!");
try
{ //what should come here to to signal taskThread to paused
Thread.sleep(3000);
//what should come here to to signal taskThread to resume
} catch (InterruptedException e)
{
}
} else
{
try
{
Thread.sleep(300);
} catch (InterruptedException e)
{
}
}
}
}});
busyThread.start();
}
}
There are two very useful classes in concurrency package - CountDownLatch and CyclicBarrier. If you need this behaviour only once, you probably want the first one (as it cannot be reset).
Thread 1 will await until notified by thread 2. Once it was counted down to 0, thread 1 will never block again at await():
CountDownLatch cdl = new CountDownLatch(1);
// thread 1:
cdl.await();
// thread 2:
cdl.countDown();
Threads will block at await() until there are exactly two threads waiting:
CyclicBarrier barrier = new CyclicBarrier(2);
// both threads:
barrier.await();
EDIT:
Here is what I came up with when modifying your code, however it is unclear to me whether it is expected behaviour.
Note a volatile keyword on the CountDownLatch - it is very important here, otherwise taskThread may cache the initial object (new CountDownLatch(0)) and hence never block.
public class Test {
private Thread taskThread;
private Thread busyThread;
private volatile CountDownLatch cdl = new CountDownLatch(0);
public static void main(String args[]) throws Exception {
Test t = new Test();
t.runTaskThread();
t.runBusyThread();
}
public void runTaskThread() {
taskThread = new Thread(() -> {
for (int x = 0; x < 100; x++) {
waitIfSystemBusy();
System.out.println("I'm doing task A for process #" + x);
sleep(1000);
waitIfSystemBusy();
System.out.println("I'm doing task B for process #" + x);
sleep(200);
waitIfSystemBusy();
System.out.println("I'm doing task C for process #" + x);
sleep(300);
waitIfSystemBusy();
System.out.println("I'm doing task D for process #" + x);
sleep(800);
System.out.println("\n\n");
}
});
taskThread.start();
}
public void runBusyThread() {
busyThread = new Thread(() -> {
while (true) {
Random rand = new Random();
int randomNum = rand.nextInt(1000);
if (randomNum < 400) {
System.out.println("Wait...system is busy!!!");
cdl = new CountDownLatch(1); // signal taskThread to pause
sleep(3000);
cdl.countDown(); // signal taskThread to resume
} else {
sleep(300);
}
}
});
busyThread.start();
}
private void waitIfSystemBusy() {
try {
cdl.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
private static void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
It would be done using the deprecated methods Thread.suspend/resume.
They are deprecated as they are deadlock prone, whereas concurrency mechanisms like locks behave in a designed explicit manner (but still deadlock prone).
I would suggest create a class that implements Runnable which simply keep track of the stages you are in
just as an example (please change accordingly)
class MyRunnable implements Runnable {
private int stage = 0; // if you want it gloabally, then use static
#Override
public void run() {
try{
switch(stage){
case 1:
System.out.println("1");
stage++;
case 2:
System.out.println("2");
Thread.sleep(2000);
stage++;
default:
stage = 0;
}
}catch (Exception e){
}
}
}
now to use such class you just need to create a new thread
for example:
public static void main(String[] args) throws Exception{
MyRunnable myRunnable=new MyRunnable();
new Thread(myRunnable).start(); //it prints 1
Thread.sleep(1000);
new Thread(myRunnable).start(); //prints 2 follow by 2 sec sleep
}
NOTE:
this example wasn't intended to answer the question exactly but rather show a logic how it can be done.
EDIT 1:
what should come here to to signal taskThread to paused
taskThread.interupt();
what should come here to to signal taskThread to resume
taskThread=new Thread(myRunnable);
taskThread.start();
Instead of sleep() I would prefer wait() and notifyAll().
have a Boolean systemBusy, implement get and set methods;
now in thread1
run(){
synchronize(something){
while(isSystemBusy()){
try{
wait();}
catch{}
}
}
}
and on the other thread
run(){
setSystemBusy(true);
//piece of code
//task finished
notifyAll();
setSystemBusy(false);
}
you can use this in multiple waiting threads just remember to set appropriate while condition false after notify all.
...
Thread showWordThread = new Thread() {
public void run() {
try {
sleep(config.delayTime * 1000);
} catch (Exception e) {
System.out.println(e.toString());
}
this.run();
}
};
showWordThread.run();
}
...
It had run for about 5 minutes before error occured:
Exception in thread "Thread-2" java.lang.StackOverflowError.
Why?
I had tried this:
Thread showWordThread = new Thread(new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(config.delayTime * 1000);
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
});
showWordThread.start();
But error still occured.
Others have explained that you should use a while loop instead. You're also trying to call the run method inside your anonymous class declaration. Additionally, you should call start, rather than run - when the new thread has started, it will call run automatically. I'd actually suggest implementing Runnable rather than extending Thread, too. So you want:
Thread showWordThread = new Thread(new Runnable() {
#Override public void run() {
while (someCondition) {
try {
Thread.sleep(config.delayTime * 1000);
// Presumably do something useful here...
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
});
showWordThread.start();
Alternatively, consider using a Timer or ScheduledExecutorService.
You are calling run method as recursively. Java holds call information(such as parameters) in stack memory so when you are calling a method recursively and there isn't any end point, stack memory will consumed and StackOverflow exception throws.
Maybe you want increasing Heap Size of JVM but this solution don't solve your problem and StackOverflow will occurred .
I guess you want run a thread continually. I recommend following code:
Thread showWordThread = new Thread()
{
public void run()
{
try
{
sleep(config.delayTime * 1000);
}
catch (Exception e)
{
System.out.println(e.toString());
}
// this.run(); this snnipet code make error
}
};
showWordThread.run();
}
Don't call run() from within the run() method. That'll definitely produce a stack overflow because you keep reentering the same method with no exit condition. Instead use a while loop.
Thread showWordThread = new Thread() {
public void run() {
while(condition) {
try {
sleep(config.delayTime * 1000);
} catch (Exception e) {
System.out.println(e.toString());
}
}
};
showWordThread.start();
}
Your code have infinity recursive, you should change the code to:
Thread showWordThread = new Thread() {
public void run() {
while (true) {
try {
Thread.sleep(config.delayTime * 1000);
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
};
showWordThread.start();
Your function calls itself each time you run it.
That results in a stack overflow.
Maybe because you call run method (this.run()) from itself?
Sorry if the question is quite simple. I am a beginner.
I have to create thread that calulates something, while the first thread works the other one have to measure if the first thread calculate the function in specified time. If not, it has to throw exception. Else it returns the answer.
I'd take the java.util.concurrent components - simple example
public void myMethod() {
// select some executor strategy
ExecutorService executor = Executors.newFixedThreadPool(1);
Future f = executor.submit(new Runnable() {
#Override
public void run() {
heresTheMethodToBeExecuted();
}
});
try {
f.get(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// do something clever
} catch (ExecutionException e) {
// do something clever
} catch (TimeoutException e) {
// do something clever
}
}
Have your thread notify a synchronization object when it is done and have your other thread wait x number of milliseconds for it to finish.
public class Main {
private static final Object mThreadLock = new Object();
static class DoTaskThread extends Thread {
public void run() {
try {
int wait = new Random().nextInt(10000);
System.out.println("Waiting " + wait + " ms");
Thread.sleep(wait);
} catch (InterruptedException ex) {
}
synchronized (mThreadLock) {
mThreadLock.notifyAll();
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
synchronized (mThreadLock) {
DoTaskThread thread = new DoTaskThread();
thread.start();
try {
// Only wait 2 seconds for the thread to finish
mThreadLock.wait(2000);
} catch (InterruptedException ex) {
}
if (thread.isAlive()) {
throw new RuntimeException("thread took too long");
} else {
System.out.println("Thread finished in time");
}
}
}
}
join is a lot simpler than using a lock.
join (millis)
Waits at most millis milliseconds
for this thread to die. A timeout of 0
means to wait forever.
Example code:
Thread calcThread = new Thread(new Runnable(){
#Override
public void run() {
//some calculation
}
});
calcThread.start();
//wait at most 2secs for the calcThread to finish.
calcThread.join(2000);
//throw an exception if the calcThread hasn't completed.
if(calcThread.isAlive()){
throw new SomeException("calcThread is still running!");
}
Have a look at http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination(long,%20java.util.concurrent.TimeUnit) which allows you to handle this without dealing with thread synchronization yourself.
I am going through the kathy sierra SCJP 1.5 Chapter 9(threads) and there it is mentioned as:
Notice that the sleep() method can throw a checked InterruptedException
(you'll usually know if that is a possibility, since another thread has to explicitly do
the interrupting), so you must acknowledge the exception with a handle or declare
I just need a sample program to know when it happens (which i can run on my machine)?
I googled but could not find any sample code to test this functionality..
Thanks in Advance
Here's an example:
public class Test
{
public static void main (String[] args)
{
final Thread mainThread = Thread.currentThread();
Thread interruptingThread = new Thread(new Runnable() {
#Override public void run() {
// Let the main thread start to sleep
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
mainThread.interrupt();
}
});
interruptingThread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("I was interrupted!");
}
}
}
To walk through it:
Set up a new thread which will sleep for a short time, then interrupt the main thread
Start that new thread
Sleep for a long-ish time (in the main thread)
Print out a diagnostic method when we're interrupted (again, in the main thread)
The sleep in the main thread isn't strictly necessary, but it means that the main thread does get to really start sleeping before it's interrupted.
public class SleepTest1 extends Thread {
#Override
public void run() {
try {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName());
Thread.sleep(1000);
Thread.currentThread().interrupt();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SleepTest1 st1 = new SleepTest1();
st1.start();
}
}