Java Multiple Threads Demo not Working - java

I'm writing a small program to see how multiple threads can be run in Java. Not sure why I'm not getting any output:
class NuThread implements Runnable {
NuThread() {
Thread t = new Thread(this, "NuThread");
t.start();
}
public void run() {
try {
for (int i=0; i<5; i++) {
Thread th = Thread.currentThread();
System.out.println(th.getName() + ": " + i);
Thread.sleep(300);
}
} catch (InterruptedException e) {
Thread th = Thread.currentThread();
System.out.println(th.getName() + " interrupted.");
}
}
}
public class MultiThreadDemo {
public static void main(String[] args) {
NuThread t1, t2, t3;
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main interrupted.");
}
}
}

You're not creating any instances of NuThread. This line:
NuThread t1, t2, t3;
... just declares three variables. It doesn't create any instances. You'd need something like:
NuThread t1 = new NuThread();
NuThread t2 = new NuThread();
NuThread t3 = new NuThread();
Having said that, making a constructor start a new thread is a little odd in itself... it might be better to remove that and just have:
// TODO: Rename NuThread to something more suitable :)
NuThread runnable = new NuThread();
Thread t1 = new Thread(runnable);
Thread t2 = new Thread(runnable);
Thread t3 = new Thread(runnable);
t1.start();
t2.start();
t3.start();
Note that it's okay to use the same Runnable for all three threads, as they don't actually use any state.

You are not creating object of NuThread. That's why thread is not starting.
And it's not the best idea to start thread in the constructor, see here.

Related

How can I access the fields of the Runnable object within my Thread

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

Why my synchronized method not working properly?

I have this synchronized method that prints counter, I have 4 Threads so I am expecting final value of my counter to be 400000 as my counter is a static variable.
but every time I run my code, it is giving me different values of counter.
Following is my code:
class MyThread implements Runnable{
private static int counter=1;
#Override
public void run() {
try {
this.syncMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void syncMethod() throws InterruptedException{
for(int i=0;i<100000;i++){
System.out.println(Thread.currentThread().getName()+" : "+counter++);
}
}
}
public class MyController {
public static void main(String[] args) throws InterruptedException {
Runnable r1=new MyThread();
Runnable r2=new MyThread();
Runnable r3=new MyThread();
Runnable r4=new MyThread();
Thread t1;
Thread t2;
Thread t3;
Thread t4;
t1=new Thread(r1,"Thread 1");
t2=new Thread(r2,"Thread 2");
t3=new Thread(r3,"Thread 3");
t4=new Thread(r4,"Thread 4");
t2.start();
t1.start();
t3.start();
t4.start();
}
}
The variable is static, but the method that you synchronized is not static. This means that it will acquire the monitor on the current instance, and every thread has a different current instance.
A simple solution is to make the syncMethod method static as well; in that case, it will take a lock on the monitor that is shared by all instances of the MyThread class:
public static synchronized void syncMethod()
Erwin Bolwidt's answer is right to solve your problem. As another way to increment a static shared counter in multiple threads safely, you can turn to AtomicLong.
Define it as this:
private static AtomicLong counter = new AtomicLong();
Increment it as:
counter.getAndIncrement();
And in the end, get the result:
counter.get();
synchronised key word in non static methods means exactly synchronize me for this methods : this two code a striclty equivalent :
public synchronised void dojob(){
//the job to do
}
et
public void dojob(){
synchronised (this){
//the job to do
}
}
in your case your synchronized methods are synchronizing on different object (t1,t2,t3 and t4) so didn't block them each other . the best solution is thaat your thread will use a common object to synchronized each other. an other point it alway better to get its thread back to do this call join here is a code to do what you want with this 2 fixes
class MyThread implements Runnable {
public static class JobDoer {
public synchronized void syncMethod() throws InterruptedException {
for (int i = 0; i < 100000; i++) {
System.out.println(Thread.currentThread().getName() + " : " + counter++);
}
}
}
private static int counter = 1;
public MyThread(JobDoer doer) {
this.doer = doer;
}
private JobDoer doer;
#Override
public void run() {
try {
doer.syncMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
JobDoer doer = new JobDoer();
Thread t1 = new Thread(new MyThread(doer), "Thread 1");
Thread t2 = new Thread(new MyThread(doer), "Thread 2");
Thread t3 = new Thread(new MyThread(doer), "Thread 3");
Thread t4 = new Thread(new MyThread(doer), "Thread 4");
t2.start();
t1.start();
t3.start();
t4.start();
t1.join();
t2.join();
t3.join();
t4.join();
}
}

Why synchronized block is giving wrong answer?

I am trying to learn synchronization. Got stuck here according to what I have learned the following code should give 8000 as the final result but I am getting a random result like below
package threads;
import java.time.LocalDateTime;
public class A implements Runnable {
String name;
static Integer j=0;
A(String name){
this.name=name;
}
#Override
public synchronized void run() {
for(int i=1;i<=1000;i++){
synchronized(this){
A.j++;
}
}
System.out.println(j);
}
package threads;
public class MainClass {
public static void main(String args[]){
Thread t1=new Thread(new A("i am thread A "));
Thread t2=new Thread(new A("i am thread B "));
Thread t3=new Thread(new A("i am thread C "));
Thread t4=new Thread(new A("i am thread D "));
Thread t5=new Thread(new A("i am thread E "));
Thread t6=new Thread(new A("i am thread F "));
Thread t7=new Thread(new A("i am thread G "));
Thread t8=new Thread(new A("i am thread H "));
t1.setPriority(Thread.MAX_PRIORITY);
t8.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
t8.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
t8.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
still getting output like 1293
2214
1403
3214
4214
5214
6224
7037
can anyone explain to me how to achieve synchronization and what is going wrong here?
It is a common mistake to think that synchronized means "critical section", and that no other threads will run while a synchronized block is running. But synchronized blocks are only exclusive with respect to other synchronized blocks that lock on the same lock.
The answers you got ("use a common lock") are right, but didn't really tell you why. The other common mistake is to think about synchronized as protecting code, when really you should be thinking about it protecting data. Any shared mutable data should be guarded by one and only one lock, and you should know exactly what that lock is. (The more complex your locking scheme, the less likely you'll know what locks guard what data.) So you should always be thinking in terms of "data X is guarded by lock L", and then make sure you acquire lock L whenever you access (read or write) that data.
This will solve the issue. You have to synchronize using a shared lock to all the threads since you are incrementing a static field. Otherwise each object will have it's own lock and increment the static field in parallel leading to a race condition. That's why you are not getting correct value which is 8000 in this case.
package bookmarks;
public class A implements Runnable {
String name;
static Integer j = 0;
private static Object lock = new Object();
A(String name) {
this.name = name;
}
#Override
public void run() {
for (int i = 1; i <= 1000; i++) {
synchronized (lock) {
A.j++;
}
}
System.out.println(j);
}
}
There are a couple of issues in the code.
Issue 1: Lock object added in synchronized(..) is not shared among
all thread instances
Issue 2: System.out.println(j); line should be in the end after t8.join(); otherwise, you will be given 8 times output.
The rectified code
public class A implements Runnable {
String name;
static Integer j = 0;
static Object lockObject = new Object();
A(String name) {
this.name = name;
}
#Override
public void run() {
for (int i = 1; i <= 1000; i++) {
synchronized (lockObject) {
A.j++;
}
}
}
public static void main(String args[]) {
Thread t1 = new Thread(new A("i am thread A "));
Thread t2 = new Thread(new A("i am thread B "));
Thread t3 = new Thread(new A("i am thread C "));
Thread t4 = new Thread(new A("i am thread D "));
Thread t5 = new Thread(new A("i am thread E "));
Thread t6 = new Thread(new A("i am thread F "));
Thread t7 = new Thread(new A("i am thread G "));
Thread t8 = new Thread(new A("i am thread H "));
t1.setPriority(Thread.MAX_PRIORITY);
t8.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
t8.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
t8.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(A.j);
}
}

Make one thread wait for another to finish

I have two thread classes: one that prints numbers from 0 to 9, and another from 100 to 109. What I want is to make the first thread wait for the other one to finish. For this, I used the join() method, but it's not working. Please tell me where I'm going wrong:
//demonstrates the use of join() to wait for another thread to finish
class AThread implements Runnable {
Thread t;
AThread() {
t = new Thread(this);
}
public void run() {
try {
for (int i=0; i<10; i++) {
System.out.println(i);
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
public void halt(Thread th) {
try {
th.join();
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
}
//a different thread class (we distinguish threads by their output)
class BThread implements Runnable {
Thread t;
BThread() {
t = new Thread(this);
}
public void run() {
try {
for (int i=100; i<110; i++) {
System.out.println(i);
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
}
public class WaitForThread {
public static void main(String[] args) {
AThread t1 = new AThread();
BThread t2 = new BThread();
t1.t.start();
t1.halt(t2.t); //wait for the 100-109 thread to finish
t2.t.start();
}
}
You call join on the thread before it has started. That doesn't work; in that case, join will return immediately, it's not going to wait until the other thread has started and stopped later. You can see this in the API documentation:
Thread.join()
This implementation uses a loop of this.wait calls conditioned on this.isAlive.
Thread.isAlive()
Tests if this thread is alive. A thread is alive if it has been started and has not yet died.
Reorder the statements in your main method
t1.t.start();
t2.t.start();
t1.halt(t2.t); //wait for the 100-109 thread to finish
edit to answer your questions in the comments:
If you want the thread in AThread to wait for the thread in BThread to finish before doing its job, then you'll need to call join in AThread.run, and change your main method:
class AThread implements Runnable {
Thread t;
Thread threadToWaitFor;
AThread(Thread threadToWaitFor) {
t = new Thread(this);
this.threadToWaitFor = threadToWaitFor;
}
public void run() {
// First wait for the other thread to finish
threadToWaitFor.join();
// ...
}
// ...
}
public class WaitForThread {
public static void main(String[] args) {
BThread t2 = new BThread();
AThread t1 = new AThread(t2.t);
t2.t.start();
t1.t.start();
}
}

Running the more than two threads in a particular order

I want the threads to run in a particular order. Suppose I have three thread T1, T2, T2 .
T1 prints 0
T2 prints 1
T3 prints 2
I want the output in the order 0 1 2, 0 1 2 for certain number of time.
If there are two threads T1 and T2. Printing 0 1, 0 1... can be done using Producer-Consumer Problem using synchronization.
Create a class UnitOfWork:
public class UnitOfWork implements Runnable
{
String text;
public UnitOfWork(String text){
this.text = text;
}
public void run(){
System.out.println(text);
}
}
And then create a single thread executor service:
ExecutorService executor = ExecutorService.newSingleThreadExecutor();
which you will use like this:
UnitOfWork uow0 = new UnitOfWork("0");
UnitOfWork uow1 = new UnitOfWork("1");
UnitOfWork uow2 = new UnitOfWork("2");
for(int i = 0; i < 5; i++){
executor.submit(uow0);
executor.submit(uow1);
executor.submit(uow2);
}
When you are unhappy with the single thread, you can start using multiple thread executor service, which will in fact run tasks concurrently.
Using the method join() in the thread class you can achieve this.
The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing,
t.join();
causes the current thread to pause execution until t's thread terminates. Overloads of join allow the programmer to specify a waiting period. However, as with sleep, join is dependent on the OS for timing, so you should not assume that join will wait exactly as long as you specify.
Like sleep, join responds to an interrupt by exiting with an InterruptedException.
Use Thread.join to ensure it terminates before the next thread starts.
public static void main(String[] args) throws InterruptedException {
final Thread th1 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Thread 1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread th2 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Thread 2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread th3 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Thread 3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
th1.start();
th1.join();
th2.start();
th2.join();
th3.start();
}
This is a minimalist piece of code which does literally what you asked for. It relies on the wait-notify mechanism.
I stand by my assesment that you do not need any threads to meet your requirement. A simple loop which prints 0-1-2 is all you really need.
import static java.lang.Thread.currentThread;
public class A {
static int coordinator, timesPrinted;
static final int numThreads = 3, timesToPrint = 300;
public static void main(String[] args) {
for (int i = 0; i < numThreads; i++) {
final int myId = i;
new Thread(new Runnable() { public void run() {
while (true) synchronized (A.class) {
if (coordinator%numThreads == myId) {
System.out.println(myId+1);
coordinator++;
if (timesPrinted++ > timesToPrint) currentThread().interrupt();
A.class.notifyAll();
}
try {A.class.wait();} catch (InterruptedException e) {break;}
}
}}).start();
}
}
}

Categories