I am trying to figure out how Thread.sleep works, so I create the following piece of code:
public static void main() {
Runnable runnable = new Runnable() {
public void run() {
try {
Thread.sleep(1000);
System.out.println("Middle");
} catch (InterruptedException e) {
}
}
};
System.out.println("Before");
Thread t2 = new Thread(runnable);
t2.start();
System.out.println("After");
However, it only prints Before and After in the console and skips the Middle.
So I am wondering whether this Thread.sleep will break the Runnable part??
On my machine output of your code is:
Before
After
Middle
If you want to print Middle before After you need to add t2.join() method call right after t2.start(). Join method explanation.
Use join () to make your main thread wait till your thread (t2) execution finishes.
public static void main(String[] args) throws InterruptedException {
Runnable runnable = new Runnable() {
public void run() {
try {
Thread.sleep(1000);
System.out.println("Middle");
} catch (InterruptedException e) {
}
}
};
System.out.println("Before");
Thread t2 = new Thread(runnable);
t2.start();
t2.join();
System.out.println("After");
Output:
Before
Middle
After
Refer to this post to know about join() : What does this thread join code mean?
Refer to this post to know about the main thread: When does the main thread stop in Java?
Related
#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();
I am new to Java multithreading. I created simple producer-consumer pattern using wait and notify but my producer is getting called only once in tbe starting.
public class ThreadApp {
public static void main(String[] args) throws InterruptedException {
ProducerConsumerWorldp = new ProducerConsumerWorld();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
p.producer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
try {
p.consumer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
class ProducerConsumerWorld{
public void producer() throws InterruptedException{
synchronized (this) {
while(true){
System.out.println("Producer thread started running");
wait();
System.out.println("Resumed Producing");
}
}
}
public void consumer() throws InterruptedException{
synchronized (this) {
while(true){
Thread.sleep(2000);
System.out.println("Consumer thread started running");
System.out.println("Press enter to consume all and start producing");
Scanner s = new Scanner(System.in);
s.nextLine();
notify();
Thread.sleep(2000);
System.out.println("consumed all");
}
}
}
}
I am creating separate threads for producer and consumer. Producer thread only gets called in the starting and then after it is never getting executed.
I tried two option to overcome this issue. first I put while condition outside of synchronized block second is given below.
class ProducerConsumerWorld{
public void producer() throws InterruptedException{
synchronized (this) {
while(true){
System.out.println("Producer thread started running");
notify();
wait();
System.out.println("Resumed Producing");
}
}
}
public void consumer() throws InterruptedException{
synchronized (this) {
while(true){
Thread.sleep(2000);
System.out.println("Consumer thread started running");
System.out.println("Press enter to consume all and start producing");
Scanner s = new Scanner(System.in);
s.nextLine();
notify();
Thread.sleep(2000);
System.out.println("consumed all");
wait();
}
}
}
}
Both works great. Which one the of the appropriate solution to use ? I am still unable to figure out why the code I put in question is not working properly.
I am still unable to figure out why the code I put in question is not working properly
The wait() in producer() releases the monitor which allows consumer() to enter its synchronized block. Then the wait() in producer() starts waiting till consumer() calls notify() and releases the monitor (i.e. exits its synchronized block). You never exit synchronized in consumer() therefore the wait() in producer() is blocked forever
I am still unable to figure out why the code I put in question is not
working properly
I've managed to fix your code, and I've attached below the fixed code snippet.
I've introduced a boolean instance variable named isConsumed for the ProducerConsumerWorld. In doing so, what essentially happens is that after Producer Thread produces, he updates the state of isConsumed to false, since he has produced something which is yet to be consumed. Afterwards, the producer notifies the the Consumer thread, that Producer has finished producing. Next, it invokes wait() on the ProducerConsumerWorld which releases Producer's lock on ProducerConsumerWorld. Then, it waits for the lock on ProducerConsumerWorld.
Meanwhile, the Consumer Thead acquires the lock on ProducerConsumerWorld, which allows it to enter the consumer method, where it checks if there is produce yet to be consumed. If so, it consumes and updates the isConsumed variable to true, and notifies the produce has been consumed. Then the consumer proceeds to releases its lock on ProducerConsumerWorld by calling wait(), and waits to reacquire the lock on ProducerConsumerWorld after Producer has consumed.
Note:
Calling notify() doesn't release a lock until the thread moves out of the synchronized block, or wait() is called, thus releasing the lock.
Source: Oracle's OCA/OCP Java SE 7 Study Guide Page 760
Code:
import java.util.Scanner;
public class ThreadApp {
public static void main(String[] args) throws InterruptedException {
ProducerConsumerWorld p = new ProducerConsumerWorld();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
p.producer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
try {
p.consumer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
}
}
class ProducerConsumerWorld{
boolean consumed = false;
public void producer() throws InterruptedException{
System.out.println("Producer thread started running");
synchronized (this) {
while(this.consumed == true){ // Consumer has consumed and is waiting for produce
System.out.println("Resumed Producing");
this.consumed = false;
notify();
wait();
}
}
}
public void consumer() throws InterruptedException{
synchronized (this) {
while(this.consumed == false){
Thread.sleep(2000);
System.out.println("Consumer thread started running");
System.out.println("Press enter to consume all and start producing");
Scanner s = new Scanner(System.in);
s.nextLine();
this.consumed = true;
System.out.println("consumed all");
notify();
wait();
}
}
}
}
This gives me an output like,
In the code and output below, t2 doesn't start until t1 finishes. Shouldn't they work parallel? Is Thread.sleep() affect whole process?
public class Main {
public static void main(String[] args) {
T t1 = new T(), t2 = new T();
t1.run();
t2.run();
}
}
class Test {
private int x;
void foo() {
synchronized (this){
System.out.println("Entered");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Exit");
}
}
}
class T extends Thread {
static Test t = new Test();
public void run() {
System.out.println("Thread started");
t.foo();
}
}
Output:
Thread started
Entered
Exit
Thread started
Entered
Exit
If you want to run these as separate threads, you need to call the Thread.start() method.
Instead, you're calling the run() method directly. The two calls will execute in the same thread as the caller.
As an aside, usually you can just subclass Runnable rather than Thread. Then you can choose to pass your Runnable to the Thread(Runnable) constructor -- or to an ExecutorService.
I am really confused on how synchronization actually work. I have this following code:
public class FunTest {
static FunTest test;
public void method() {
synchronized (test) {
if (Thread.currentThread().getName() == "Random1") {
try {
wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
} else {
notify();
}
}
}
public static void main(String[] args) {
test = new FunTest();
final FunTest t0 = new FunTest();
Thread t1 = new Thread(new Runnable() {
public void run() {
t0.method();
}
});
Thread t3 = new Thread(new Runnable() {
public void run() {
t0.method();
}
});
t1.setName("Random1");
t3.setName("Random2");
t1.start();
t3.start();
}
}
The code throws IllegalMonitorStateException when run. I don't understand why this is happening. Is it not possible to acquire lock this way?
If I replace test with this in synchronization block it works fine though. Why is this so?
You're opening a monitor block on test, but your applying wait() and notify() to this.
According to javadoc of wait()
"The current thread must own this object's monitor"
In your case it is not.
changing t0.method(); to test.method() will work. Not sure about your usecase though.
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();
}
}