I learned that threads can lock onto "the resources", let's say an object, they're using so that only one at a time is allowed to use and modify it which is the problem of synchronization. I created two different instances of one class and fed it to my threads, trying to make sure they're locking on different "resources". How ever they still behave as though they've locked on same resources? I'm confused as I haven't had any experience and knowledge regarding threads.
So this is a code I modified from an online tutorial to try what I was thinking about:
public class TestThread {
public static void main(String args[]) {
PrintDemo PD1 = new PrintDemo("No.1"); //just prints from 1 to 5
PrintDemo PD2 = new PrintDemo("No.2");
ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD1 );
ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD2 );
T1.start();
T2.start();
// wait for threads to end
try {
T1.join();
T2.join();
} catch ( Exception e) {
System.out.println("Interrupted");
}
}
}
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
PrintDemo PD;
ThreadDemo( String name, PrintDemo pd) {
threadName = name;
PD = pd;
}
public void run() {
synchronized(PD) {
PD.printCount();
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
class PrintDemo {
private String name;
PrintDemo(String name) {
this.name = name;
}
public void printCount() {
try {
for(int i = 5; i > 0; i--) {
System.out.println(name + " Counter --- " + i );
}
} catch (Exception e) {
System.out.println("Thread interrupted.");
}
}
}
It should be different each time I run, but it always the same:
output:
Starting Thread - 1
Starting Thread - 2
No.1 Counter --- 5
No.1 Counter --- 4
No.1 Counter --- 3
No.1 Counter --- 2
No.1 Counter --- 1
Thread Thread - 1 exiting.
No.2 Counter --- 5
No.2 Counter --- 4
No.2 Counter --- 3
No.2 Counter --- 2
No.2 Counter --- 1
Thread Thread - 2 exiting.
edit #1: I put the entire code as you asked. i also tested the code without overriding start. it had the same result.
If you add a
Thread.sleep(1000)
between each tick of your PrintDemo, you will likely see that both threads do 5, then 4, then 3, etc. Right now the first thread is being too fast, it completes faster than the 2nd thread can be started by the main thread.
Synchronization has no effect here, both threads synchronize on different resources, which has no effect. After proving (with the Thread.sleep) that both threads execute at the same time, then add synchronization on a shared object, and both threads will fully execute one after the other, even with the waiting.
The problem is in your ThreadDemo.start() method.
Your ThreadDemo class is declared with extends Thread, but you never actually use it as a thread. Instead, the real thread objects are created inside ThreadDemo.start().
t = new Thread (this, threadName);
t.start ();
Here's what probably is happening:
Main thread calls T1.start(). It creates a new thread, which takes some time, and then it starts the thread.
The new thread starts printing its five lines, while the main thread simultaneously calls T2.start().
The T2.start() call creates another new thread, which takes some time. Meanwhile, the other thread still is printing. It doesn't print very many lines, and system.out is buffered, so chances are, it is able to print all of them before any actual I/O happens. Meanwhile...
...The main thread still is creating that T2 thread. It takes some time.
Finally, the main thread is able to start the T2 thread, which prints its five lines, and...
...end of story. That's how it probably goes down.
Related
Can someone help me to solve this multi-threading problem ?
The program should initiate three threads with a common resource. Each thread should print a incremented count value. Sample output is mentioned below. where T1,T2 and T3 are threads.
T1 T2 T3
1 2 3
4 5 6
7 8 9
My current code:
public class RunnableSample implements Runnable {
static int count = 0;
public void run() {
synchronized (this) {
count++;
System.out.println(
"Current thread : Thread name :" + Thread.currentThread().getName()
+ " Counter value :" + count
);
}
}
}
//main method with for loop for switching between the threads
public class ThreadInitiator {
public static void main(String[] args) {
RunnableSample runnableSample = new RunnableSample();
Thread thread1 = new Thread(runnableSample, "T1");
Thread thread2 = new Thread(runnableSample, "T2");
Thread thread3 = new Thread(runnableSample, "T3");
for (int i = 0; i < 9; i++) {
thread1.start();
thread2.start();
thread3.start();
}
}
}
Create a synchronized method to increment the value. When a method is identified as synchronized, only one thread can access it at a time and the other threads wait for the initial thread to complete method execution before they can access the method.
Pls check How to synchronize a static variable among threads running different instances of a class in java?
I am trying out codes with multiple threads.
Below is my code:
package com.thread.practice;
public class ThreadPratice1 {
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r, "Thread 1");
Thread t2 = new Thread(r, "Thread 2");
t1.start();
t2.start();
}
}
package com.thread.practice;
public class MyRunnable implements Runnable {
private static int i = 0;
#Override
public void run() {
for(i = 0; i <10;i++){
System.out.println("Thread: "+ Thread.currentThread().getName()
+" value of i: "+i);
try {
//System.out.println("Thread: "+ i);
Thread.sleep(1000);
//System.out.println("inside runnable: "+Thread.currentThread().getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
But in the output it is always printing the value of i as 0 twice in the beginning.
Output is coming kind of like this:
Thread: Thread 1 value of i: 0
Thread: Thread 2 value of i: 0
Thread: Thread 1 value of i: 2
Thread: Thread 2 value of i: 2
Thread: Thread 1 value of i: 3
Thread: Thread 2 value of i: 4
Thread: Thread 1 value of i: 5
Thread: Thread 2 value of i: 6
Thread: Thread 1 value of i: 7
Thread: Thread 2 value of i: 8
Thread: Thread 1 value of i: 9
May someone please help me in understanding this issue?
Because the value of i at the begging of the execution of the two threads is 0.
In other words, thread one and thread two stared almost at the same time, so the two of them set the i to 0 for the first loop.
for(i = 0; i <10;i++) {
Then the value changes between thread because you made i static. so it will be shared between your two threads.
You made "i" static, which means it will be the same over all threads and objects. Take away the static modifier and your code will work properly.
edit: I misinterpreted what you asked- don't set i to 0 in the for loop, it will look something like this:
for(;i<10;i++) { /*mycode*/}
One of these two is probably what you want anyway, your question was a little bit vague
value of i is incremented by the for loop only after the loop is executed. Execution of for loop takes a finite amount of time. Since you are starting the threads together (almost), both the threads may or may not print i after the other thread has finished one loop. Since you are not doing to ensure thread safety, the result will be unpredictable like the one you got.
First, You shouldn't use the primitive int type for concurrency, it's not thread safe and it maybe will cause Race Condition,
and try to use AtomicInteger to replace int, it's thread safe. the example maybe:
public class ThreadPratice1 {
public static void main(String[] args) {
AtomicInteger number = new AtomicInteger(0);
MyRunnable r = new MyRunnable(number);
Thread t1 = new Thread(r, "Thread 1");
Thread t2 = new Thread(r, "Thread 2");
t1.start();
t2.start();
}
}
class MyRunnable implements Runnable {
private AtomicInteger number;
public MyRunnable(AtomicInteger number) {
this.number = number;
}
#Override
public void run() {
while (number.get() < 10) {
System.out.println("Thread: " + Thread.currentThread().getName()
+ " value of i: " + number.getAndIncrement());
}
}
}
This question already has an answer here:
Thread not returning after notifyall()
(1 answer)
Closed 7 years ago.
I am trying to create two threads to act as counters. When one thread decrements its counter, it should toggle the value of the shared boolean flag field, call the notifyAll() method and release the other thread from the wait() method being called. The logic field serves as a means to avoid deadlock, i.e. one thread will call the wait() method when the flag field has a value of true, the other thread will call it when the flag field has a value of false. You can see the way I run the threads created from this class, as well as the expected output below. The problem is that both threads get stuck on the wait() method at the same time and only the first line of output goes through.
The expected output:
Thread No.1 4
Thread No.2 4
Thread No.1 3
Thread No.2 3
Thread No.1 2
Thread No.2 2
Thread No.1 1
Thread No.2 1
Thread No.1 0
Thread No.2 0
The actual output:
Thread No.2 4
The counter class:
public class CounterThread implements Runnable {
private long counter;
private static int threadNumber = 0;
private int index = 0;
private static boolean flag = true;
private boolean logic;
public CounterThread(long counter, boolean logic) {
index = ++threadNumber;
this.counter = counter;
this.logic = logic;
}
private synchronized void toggleFlag() {
flag = !flag;
notifyAll();
}
#Override
public synchronized void run() {
while (counter > 0) {
while (flag==logic) {
try {
wait();
} catch (InterruptedException e) {
}
}
counter--;
System.out.println("Thread No. " + index + " " +counter);
toggleFlag();
}
}
}
The way I run it:
public final class CounterThreadRun {
public static void main(String[] args) {
CounterThread counter1 = new CounterThread(5, true);
CounterThread counter2 = new CounterThread(5, false);
Thread thread1 = new Thread(counter1);
Thread thread2 = new Thread(counter2);
thread1.start();
thread2.start();
}
}
Because you're not notifying the thread that is waiting. You're only notifying the current thread, i.e. yourself. You need a shared object, perhaps a static in the class, that is used for both wait() and notifyAll().
i heard, sleep() will lock the current sync method/block
But here, when i call sleep() on thread 1, thread 2 is able to access the same block? Can anyone Explain?
Main.java
public class Main {
public static void main(String args[])
{
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
System.out.println("going to start t1");
t1.start();
System.out.println("going to start t2");
t2.start();
}
}
=====================================================================
Thread1.java
public class Thread1 extends Thread{
public void run() {
Syncc s1 = new Syncc();
s1.me("T1:");
}
}
=====================================================================
Thread2.java
public class Thread2 extends Thread{
public void run() {
Syncc s2 = new Syncc();
s2.me("T2:");
}
}
=====================================================================
Syncc.java
public class Syncc{
public void me(String s){
synchronized(this){
for(int i=0; i<=5; i++)
{
System.out.println(s+" "+" "+i);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
==========================================
Output:
going to start t1
going to start t2
T2: 0
T1: 0
T2: 1
T1: 1
T1: 2
T2: 2
T1: 3
T2: 3
T1: 4
T2: 4
T2: 5
T1: 5
BUT according to sleep() method, it should not unlock the current synchronization block right? if so the out put should be..
going to start t1
going to start t2
T1: 0
T1: 1
T1: 2
T1: 3
T1: 4
T1: 5
T2: 0
T2: 1
T2: 2
T2: 3
T2: 4
T2: 5
i mean after thread 1 execution only thread 2 should start right?
Whats the issue?
This is because you have two different instances of Syncc in play here. Each thread has its own copy of Syncc.
Try doing the same with a single instance. You could also synchronize on the static context and try.
To simulate, modify Thread1 and Thread2 to accept an instance of Syncc.
public class Thread1 extends Thread {
private Syncc syncc;
public Thread1(Syncc syncc) {
this.syncc = syncc;
}
public void run() {
this.syncc.me("T1:");
}
}
You can then start them as so:
public static void main(String args[]) {
Syncc syncc = new Syncc();
Thread1 t1 = new Thread1(syncc);
Thread2 t2 = new Thread2(syncc);
System.out.println("going to start t1");
t1.start();
System.out.println("going to start t2");
t2.start();
}
Rules of Sleep, Yield and Join
Sleeping is used to delay execution for a period of time, and no locks are
released when a thread goes to sleep.
A sleeping thread is guaranteed to sleep for at least the time specified in
the argument to the sleep() method (unless it's interrupted), but there is
no guarantee as to when the newly awakened thread will actually return to
running.
The sleep() method is a static method that sleeps the currently executing
thread's state. One thread cannot tell another thread to sleep.
The setPriority() method is used on Thread objects to give threads
a priority of between 1 (low) and 10 (high), although priorities are not
guaranteed, and not all JVMs recognize 10 distinct priority levels—some
levels may be treated as effectively equal.
If not explicitly set, a thread's priority will have the same priority as the
priority of the thread that created it.
The yield() method may cause a running thread to back out if there are
runnable threads of the same priority. There is no guarantee that this will
happen, and there is no guarantee that when the thread backs out there
will be a different thread selected to run. A thread might yield and then
immediately reenter the running state.
The closest thing to a guarantee is that at any given time, when a thread
is running it will usually not have a lower priority than any thread in the
runnable state. If a low-priority thread is running when a high-priority thread
enters runnable, the JVM will usually preempt the running low-priority
thread and put the high-priority thread in.
When one thread calls the join() method of another thread, the currently
running thread will wait until the thread it joins with has completed. Think
of the join() method as saying, "Hey thread, I want to join on to the end
of you. Let me know when you're done, so I can enter the runnable state."
http://www.amazon.com/SCJP-Certified-Programmer-Java-310-065/dp/0071591060
You have created two Synch objects each object corresponding to one thread . Each object has its own copy of me. Hence when your start each thread, withing the run method the thread is calling its own copy of the function me. Since the two thread act only on their copy this works like a single thread scenario. If you do want to test a multithread scenario then make the method me static(class level method) and apply a class level lock.
Thread1.java
public class Thread1 extends Thread{
public void run() {
Syncc.me("T1:");
}
}
Thread2.java
public class Thread2 extends Thread{
public void run() {
Syncc.me("T2:");
}
}
Syncc.java
public class Syncc{
public static void me(String s){
synchronized(Syncc.class){
for(int i=0; i<=5; i++)
{
System.out.println(s+" "+" "+i);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Recently I have gone through with one simple threading program, which leads me some issues for the related concepts... My sample program code looks like :
class NewThread implements Runnable {
Thread t;
NewThread() {
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start(); // Start the thread
}
public void run() {
try {
for (int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
class ThreadDemo {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {
for (int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
Now this program giving me the output as follows :
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
So, that's very much clear to me. But as soon as I am replacing the object creation code (calling of a NewThread class constructor) to as follows :
NewThread nt = new NewThread(); // create a new thread
the output becomes a bit varied like as follows :
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Child Thread: 3
Main Thread: 4
Child Thread: 2
Child Thread: 1
Main Thread: 3
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
And some times it's giving me same output in both the cases. So, i am not getting the exact change in both the scenario.
I would like to know that you the variation in the output is coming here ?
Thanks in advance...
The changed output is due to nature of both OS process scheduling and JVM thread scheduling. Even if you take out the second thread there is no guarantee that your thread will wake-up exactly after 500ms.
I'm not sure I understand the change that you mention, but the scheduling is non-deterministic, i.e., it may schedule the threads differently in different runs of the application.
Another thing; creating and starting a new thread in the constructor isn't really best practice. Have you considered letting NewThread extend Thread? Like this:
class NewThread extends Thread {
NewThread(String str) {
super(str);
System.out.println("Child thread: " + this);
}
public void run() {
try {
for (int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
public class ThreadDemo {
public static void main(String args[]) {
new NewThread("Demo Thread").start();
try {
for (int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
You have two threads, one which does something about every half second, one which does something about every second.
The JVM and OS makes no guarantee which of the threads available for scheduling gets run at a given time. Alternatively, if you have multiple cores then both threads could be running at the same time, and competing for a lock on the System.out that stops two threads printing at the same time - if you send the output one character at a time instead of using println, then the characters from both thread's output might be mixed together.
Your output shows that at one second and at two seconds, which of the two threads prints its output it is not predictable. This is as expected.
It makes no difference in this case whether or not you assign the NewThread object to a local variable. The object is not eligible for garbage collection while the thread it is running in is running (assuming Threads hold a reference to their runnable), and nothing else uses the local variable. So the difference after that change in the code is just the randomness in the scheduling, not the effect of the change.
As mentioned above, this is normal behaviour. If you need some tasks started at a specific time and/or at a fixed interval, then the Timer's scheduleAtFixedRate() may give you a better result.
Are both outputs correct for both programs? Yes.
The answer is the output is undefined. The particular (correct) output you get each time could depend on just about anything, including minor variations in the compiled bytecode. (It might be worth checking this with javap -c, just to be sure the difference in code is a possible cause.)
In general if you have two threads doing things in parallel, you can't be sure of the ordering of their combined output unless you synchronise them somehow.