I am expecting below to increment c value to be 2. But I am always getting 1 output even after the 2nd thread started.
package test.main;
public class TestThread implements Runnable {
private int c=0;
#Override
public void run() {
synchronized(this){
c=c+1;
//wait(1000);
go();
}
}
private void go() {
System.out.println("Thread name :"+Thread.currentThread()+" in go() : "+c);
}
public static void main(String[] args) throws InterruptedException {
System.out.println("main()");
Thread t1 = new Thread(new TestThread(),"thread1");
Thread t2 = new Thread(new TestThread(),"thread2");
t1.start();
t2.start();
}
}
In thread t1 and t2 you are passing two completely different objects. So in both cases it is incrementing their own c which are not related to each other.
Use a single object
TestThread tt = new TestThread();
Thread t1 = new Thread(tt,"thread1");
Thread t2 = new Thread(tt,"thread2");
You have created two thread objects.
Thread t1 = new Thread(new TestThread(),"thread1");
Thread t2 = new Thread(new TestThread(),"thread2");
And each thread object has its own copy of c as its not class level variable. Its instance variable.
So, it will not give you a value 2
Each TestThread object has its own copy of c, so each will be incremented only once.
Thread t1 = new Thread(new TestThread(),"thread1");
Thread t2 = new Thread(new TestThread(),"thread2");
You are creating two different instances of TestThread and
private int c=0;
is an instance variable(not a class variable). So it is expected for c to be 1 after run() is executed for each Thread.
Related
I am learning synchronization in Java and I cant find out why I cant get 24000 as a result for "c.count". When I run the code I get 23674, 23853, etc.
Do you have any idea why?
public class Counter {
public int count = 0;
public static void main(String[] args) throws InterruptedException {
Counter c = new Counter();
ThreadT t1 = new ThreadT(c);
ThreadT t2 = new ThreadT(c);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(c.count);
}
}
class ThreadT extends Thread {
Counter c;
ThreadT(Counter c) {
this.c = c;
}
public void run() {
for (int i = 0; i < 12000; i++) {
add();
}
}
synchronized void add() {
c.count++;
}
}```
Notice that t1 calls add on the t1 object while t2 calls add on the t2 object. While add is synchronized, t1 and t2 are two different objects, so the two threads are not synchronizing with each other.
Each thread calls a synchronized method on its own thread object, so it synchronizes only with itself. You need both threads to call synchronized methods on the same object.
I am trying to get the time it takes the CPU to perform a context switch so I have a class taking the System time in nanoseconds and I put it into some threads but I need to get those numbers and perform computations on it but I don't know how I can access it.
This is my main function.
public class GroupNinePipe{
public static void main(String[] args)
{
Thread t1 = new Thread(new OSProj2("Thread1"));
Thread t2 = new Thread(new OSProj2("Thread2"));
Thread t3 = new Thread(new OSProj2("Thread3"));
Thread t4 = new Thread(new OSProj2("Thread4"));
Thread t5 = new Thread(new OSProj2("Thread5"));
Thread t6 = new Thread(new OSProj2("Thread6"));
OSProj2 n = new OSProj2("Thread 8");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
}
Class taking system time.
public class OSProj2 implements Runnable {
String name;
long time;
public OSProj2(String x)
{
name = x;
}
public void run()
{
try{
time = System.nanoTime();
System.out.printf("%s sys time: %d\n", name, time);
this.getTime();
}
catch (Exception e){}
}
public long getTime()
{
return time;
}
}
I know the name of the class says Pipe but I don't use one.
I dont know if this is the right way to go about it but nevertheless, your code becomes like this
Runnable osProj2 = new OSProj2("Thread1");
Thread t1 = new Thread(osProj2);
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(osProj2.getTime()); // for example
The t1.join() will block until your thread finish running, hope i helped
This question already has answers here:
What's the difference between Thread start() and Runnable run()
(14 answers)
Closed 7 years ago.
Consider this simple try for a multithreading example :
public class LetsMutexThreads {
public static Object MUTEX = new Object();
private static class Thread1 extends Thread {
public void run() {
synchronized (MUTEX)
{
System.out.println("I'm thread 1 , goint to take a nap...");
try
{
MUTEX.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("T1 : That's it , I'm done ...");
}
}
}
private static class Thread2 extends Thread {
public void run() {
synchronized (MUTEX)
{
System.out.println("Thread 2 : Let's rock N roll !");
System.out.println("Waking up my buddy T1 ...");
MUTEX.notify();
}
}
}
public static void main(String[] args)
{
Thread2 t2 = new Thread2();
Thread1 t1 = new Thread1();
t1.run();
t2.run();
}
}
I'm trying to allow Thread1 to go to sleep with the wait , and then let Thread2
to use notify() to wake Thread1 , but he doesn't get a chance .
Why does the wait() of Thread1 affects the Main Thread from executing t2.run(); ?
You must not attempt to start a thread using the run() method. It does not actually create a new thread, it runs the code in the current thread. Use thread.start() instead in order to have your code executed in a separate (new) thread
This is wrong:
Thread2 t2 = new Thread2();
Thread1 t1 = new Thread1();
t1.run();
t2.run();
Change it to this:
Thread2 t2 = new Thread2();
Thread1 t1 = new Thread1();
t1.start();
t2.start();
For this below program, the ans is --> print : printName , then wait for 5 seconds then print : printValue
But as far as I know that its up to JVM to pick a thread and start its run method. So why it cannot be (printvalue printname and then 5 sec pause).
Note : I understand the conept of synchornized method but how we are sure here that JVM will always pick the thread t1 as its first thread.
class B {
public synchronized void printName() {
try {
System.out.println("printName");
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
}
}
public synchronized void printValue() {
System.out.println("printValue");
}
}
public class Test1 extends Thread {
B b = new B();
public static void main(String argv[]) throws Exception {
Test1 t = new Test1();
Thread t1 = new Thread(t, "t1");
Thread t2 = new Thread(t, "t2");
t1.start();
t2.start();
}
public void run() {
if (Thread.currentThread().getName().equals("t1")) {
b.printName();
} else {
b.printValue();
}
}
}
In this context, the synchronize just means that they can't run at the same time, not that they have to run in order. If you want them to run in order, then you don't want threads, or you want a more sophisticated queuing mechanism.
So, you are correct in that the it could either be "printName" pause "printValue" or "printValue" "printName" pause.
If you run the program multiple times, you'll likely see the first one more frequently. You will see the second output occasionally. The skew is because there is a slight delay between the start() on thread 1 and start() on thread 2.
how we are sure here that JVM will always pick the thread t1 as its first thread.
You can never be sure that the t1 thread will start running before the t2 thread starts running. If you need the t1 thread to do something before the t2 thread does some other thing, then you will have to use some synchronization object (e.g., a Semaphore) to make t2 wait.
Semaphore semaphore = new Semaphore(0);
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
doTheThingThatHasToBeDoneFirst();
semaphore.release();
doOtherStuff();
}
}).start();
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
semaphore.acquire(); //will not return until t1 thread calls release().
doOtherOtherStuff();
}
}).start();
But that is not really a smart way to use threads. Why not just do this instead?
doTheThingThatHasToBeDoneFirst();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
doOtherStuff();
}
}).start();
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
doOtherOtherStuff();
}
}).start();
As a rule of thumb, the more synchronization you have between your threads, the less benefit you get from using threads. If you want certain things to happen in a certain order, you should do those things in that order in a single thread.
The trick to using threads is to design your program so that there are useful things it can do where order does not matter.
class Untitled {
public static void main(String[] args) {
MyRunnable r1 = new MyRunnable();
Thread t1 = new Thread(r1,"Thread 1:");
Thread t2 = new Thread(r1,"Thread 2:");
t1.start();
t2.start();
}
}
class MyRunnable implements Runnable
{
String s1 = "Hello World";
String s2 = "Hello New World";
public void run()
{
synchronized(s1)
{
for(int i =0;i<3;++i)
System.out.println(Thread.currentThread().getName()+s1);
}
synchronized(s2)
{
for(int i = 0;i<3;++i)
System.out.println(Thread.currentThread().getName()+s2);
}
}
}
OUTPUT:
Thread 1:Hello World
Thread 1:Hello World
Thread 1:Hello World
Thread 1:Hello New World
Thread 2:Hello World
Thread 1:Hello New World
Thread 2:Hello World
Thread 1:Hello New World
Thread 2:Hello World
Thread 2:Hello New World
Thread 2:Hello New World
Thread 2:Hello New World
Why can't Thread2 execute the second synchronized block in the run() method when Thread1 is executing the first synchronized block even though lock objects are different.Does Thread2's execution wait at the first synchronized block till Thread1 leaves that block??
If so how to make both synchronized blocks run concurrently??
Does Thread2's execution wait at the first synchronized block till Thread1 leaves that block??
Yes that's the idea - thread2 executes the blocks one after the other. If it is blocked and can't enter the first one, it will wait there until the s1 lock becomes available.
If so how to make both synchronized blocks run concurrently??
You would need to split them in two different runnables and use one thread for each.
Because within the run method statements are executed in sequentially not parallely.
So who ever Thread 1 or Thread 2 acquire the lock of s1 other will wait untill it is released.
The two blocks are one after the other, which means that Thread 2 has to go though block 1 before going through block 2
Why can't Thread2 execute the second synchronized block in the run()
method when Thread1 is executing the first synchronized block
Code is executed line by line, The execution doesnt jump to next block and Thread 2 waits for Thread 1 to leave the 1st Synchronized block.
Does Thread2's execution wait at the first synchronized block till
Thread1 leaves that block
Yes.
If so how to make both synchronized blocks run concurrently??
So keep them In seperate Runnable Instances. and Not one after the other in a Sequence.
It is simply the compiler execute the code i.e. compiler execute code in sequence the way they are written. thread 2 cannot skip first block of code. it will first execute first block then others.
Here's an example of getting them both to run concurrently. Note that not only have I put each loop in a separate thread but I have reduced the scope of the synchronization to just the print.
public class Test {
static class MyRunnable implements Runnable {
final String s1 = " Hello World - ";
final String s2 = " Hello New World - ";
static final int n = 10;
#Override
public void run() {
// Two loops in two threads.
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < n; ++i) {
// Scope reduced.
synchronized (s1) {
System.out.println(Thread.currentThread().getName() + s1 + i);
}
}
}
}, Thread.currentThread().getName() + "(a)").start();
// Two loops in two threads.
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < n; ++i) {
// Scope reduced.
synchronized (s2) {
System.out.println(Thread.currentThread().getName() + s2 + i);
}
}
}
}, Thread.currentThread().getName() + "(b)").start();
}
}
public void test() {
MyRunnable r1 = new MyRunnable();
Thread t1 = new Thread(r1, "Thread 1:");
Thread t2 = new Thread(r1, "Thread 2:");
t1.start();
t2.start();
}
public static void main(String args[]) {
new Test().test();
}
}
class ThreadExample {
public static void main(String[] args) {
MyRunnable15756 r1 = new MyRunnable15756();
Thread t1 = new Thread(r1,"Thread 1:");
Thread t2 = new Thread(r1,"Thread 2:");
t1.start();
t2.start();
}
}
class MyRunnable15756 implements Runnable
{
String s1 = "Hello World";
String s2 = "Hello New World";
Runnable runnable1 = new Runnable(){
#Override
public void run() {
synchronized(s1)
{
for(int i =0;i<30;++i)
System.out.println(Thread.currentThread().getName()+s1);
}
}
};
Runnable runnable2 = new Runnable(){
#Override
public void run() {
synchronized(s2)
{
for(int i = 0;i<30;++i)
System.out.println(Thread.currentThread().getName()+s2);
}
}
};
public void run()
{
new Thread(runnable1).start();
new Thread(runnable2).start();
}
}