Java multithreading query - java

Hi I am a newbie in concurrent programming domain, I was testing the below code and seems the while loop is not terminating for threads. Could someone help explain whats happening here.
public class PrimePrinter{
public long counter = 0;
public synchronized long getCounter() {
return counter++;
}
public Thread makeThread() {
Runnable rn = new Runnable() {
/* (non-Javadoc)
* #see java.lang.Runnable#run()
*/
#Override
public void run() {
while (counter < 100) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " : " +getCounter());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
return new Thread(rn);
}
public static void main(String[] args) {
int n = 10;
Thread[] threads = new Thread[10];
PrimePrinter pp = new PrimePrinter();
for(int i = 1; i < n; i++) {
threads[i] = pp.makeThread();
threads[i].start();
}
}
}
Last few lines of output
Thread-4 : 81
Thread-5 : 87
Thread-7 : 91
Thread-5 : 97
Thread-2 : 95
Thread-4 : 98
Thread-6 : 96
Thread-8 : 90
Thread-1 : 93
Thread-3 : 92
Thread-0 : 94
Thread-2 : 99
Thread-6 : 107
Thread-3 : 103
Thread-0 : 104
Thread-1 : 105
Thread-8 : 106
Thread-5 : 102
Thread-4 : 101
Thread-7 : 100

This is not working for one reason that is crucial not to miss. Consider the way your code actually runs. It checks the counter value, then sleeps, THEN prints THEN increments.
You have 9 threads running at once. Then, 8 of these threads check the value, and at the time, the value is less than 100. So they pass the test and keep going. All 8 then sleep for 1000ms. Meanwhile, your other thread has just incremented the value... and 8 more are about to come out of their sleep.
So, if your value is 99 (which it inevitably will be), you'll now get a value of 100 from the thread that just incremented. Then, those 8 that already passed the test are also going to be incrementing, giving the counter a resulting value of 108.
However, the very last thread to run will show a value of 107 because you print THEN increment for all runs.
If you did this the other way around (like in the code below), you would not run into this problem.
The following code works correctly:
public class PrimePrinter {
public long counter = 0;
public synchronized long getCounter() {
return counter;
}
public synchronized void incrementCounter() {
counter++;
}
public Thread makeThread() {
Runnable rn = new Runnable() {
/*
* (non-Javadoc)
*
* #see java.lang.Runnable#run()
*/
#Override
public void run() {
while (getCounter() < 100) {
try {
incrementCounter();
System.out.println(Thread.currentThread().getName()
+ " : " + getCounter());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
return new Thread(rn);
}
public static void main(String[] args) {
int n = 10;
Thread[] threads = new Thread[10];
PrimePrinter pp = new PrimePrinter();
for (int i = 1; i < n; i++) {
threads[i] = pp.makeThread();
threads[i].start();
}
}
}

Each thread waits a second after having tested that counter < 100, during this second, other threads can increment the counter.
UPDATE: You could do something like this:
while (true) {
long current = getCounter();
if (current >= 100) {
break;
}
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " : " + current);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

Related

Can FairSync guarantee the order of execution?

My first question, Thank for your help!
I'm trying to print odd and even numbers 1~100 alternatively using two threads.
Expected results:
pool-1-thread-1=> 1
pool-1-thread-2=> 2
pool-1-thread-1=> 3
pool-1-thread-2=> 4
......
pool-1-thread-1=> 99
pool-1-thread-2=> 100
I think i can use FairSync, but it can only guarantee that most of the print is correct. like this:
pool-1-thread-1=> 55
pool-1-thread-2=> 56
pool-1-thread-1=> 57
pool-1-thread-2=> 58
pool-1-thread-2=> 59 //※error print※
pool-1-thread-1=> 60
pool-1-thread-2=> 61
pool-1-thread-1=> 62
I don't know why is the order lost in very few cases?
You can criticize my code and my English.
Here is my code:
private static final int COUNT = 100;
private static final int THREAD_COUNT = 2;
private static int curr = 1;
static ReentrantLock lock = new ReentrantLock(true);
static ExecutorService executorService = Executors.newCachedThreadPool();
public static void main(String[] args) {
Runnable task = () -> {
for (; ; ) {
try {
lock.lock();
if (curr <= COUNT) {
System.out.println(Thread.currentThread().getName() + "=> " + curr++);
} else {
System.exit(0);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
for (int i = 0; i < THREAD_COUNT; i++) {
executorService.execute(task);
}
}
No dear your implementation is not correct. Which thread get's the opportunity to RUN is decided by the OS. Thread 1 & 2 will execute one after another cannot be guaranteed.
You can fix your code by checking the previous value of the variable curr and if the value is not what this thread expects don't increment and print.
for eg :
if(curr.threadName.equals("Thread 2") && (curr%2 !=0))
{
// Print
// Increment
}
You cant use single lock to achieve this. Even ReentrantLock gives fairness but it cant control thread schedule.
We can achieve throw inter thread communication like Semaphore. Semaphore controls the thread execution.
We create two threads, an odd thread, and an even thread. The odd thread would print the odd numbers starting from 1, and the even thread will print the even numbers starting from 2.
Create two semaphores, semOdd and semEven which will have 1 and 0 permits to start with. This will ensure that odd number gets printed first.
class SharedPrinter {
private Semaphore semEven = new Semaphore(0);
private Semaphore semOdd = new Semaphore(1);
void printEvenNum(int num) {
try {
semEven.acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().getName() + num);
semOdd.release();
}
void printOddNum(int num) {
try {
semOdd.acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().getName() + num);
semEven.release();
}
}
class Even implements Runnable {
private SharedPrinter sp;
private int max;
// standard constructor
#Override
public void run() {
for (int i = 2; i <= max; i = i + 2) {
sp.printEvenNum(i);
}
}
}
class Odd implements Runnable {
private SharedPrinter sp;
private int max;
// standard constructors
#Override
public void run() {
for (int i = 1; i <= max; i = i + 2) {
sp.printOddNum(i);
}
}
}
public static void main(String[] args) {
SharedPrinter sp = new SharedPrinter();
Thread odd = new Thread(new Odd(sp, 10),"Odd");
Thread even = new Thread(new Even(sp, 10),"Even");
odd.start();
even.start();
}
Refer : here

Thread sequencing with Java 8

I have a simple program for two threads to print, incremental numbers, alternately.
So,
first thread prints : 1
Second thread prints : 2
first thread prints : 3... and so on
I am able to use 'Thread' class to do this. But I want to see how to use Executor class to do this.
With the following code .... executor class does NOT seem to work. Any pointers ??
Code :
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LocksPackagePractice {
private int i = 0;
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Runnable r = () -> {
for(int x = 0; x < 5; x++){
printValue();
}
printValue();
};
public static void main(String[] args) {
new LocksPackagePractice().trigger();
}
void trigger(){
ExecutorService service = Executors.newFixedThreadPool(2);
service.execute(r);
}
void printValue(){
lock.lock();
try {
i++;
System.out.println(Thread.currentThread().getName() + " and value is = " + i);
condition.signal();
condition.await();
} catch(InterruptedException e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
Made some changes in your program. Run it and check if it solves the confusion.
public class LocksPackagePractice {
private int i = 0;
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Runnable r = () -> {
printValue();
};
public static void main(String[] args) {
new LocksPackagePractice().trigger();
}
void trigger() {
ExecutorService service = Executors.newFixedThreadPool(2);
service.submit(r);
for (int i = 0; i < 5; i++) {
service.execute(r);
}
}
void printValue() {
lock.lock();
try {
i++;
System.out.println(Thread.currentThread().getName() + " and value is = " + i);
condition.signal();
condition.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
This will give you following output
pool-1-thread-1 and value is = 1
pool-1-thread-2 and value is = 2
pool-1-thread-1 and value is = 3
pool-1-thread-2 and value is = 4
pool-1-thread-1 and value is = 5
pool-1-thread-2 and value is = 6
I'm not sure, but do you need input to be ordered ? Because you use blocking operations (locks) and it is not good in case of performance.
This code :
private AtomicInteger number = new AtomicInteger(0);
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
ForTestApplication testApplication = new ForTestApplication();
for (int i = 0; i < 100; i++) {
executor.execute(testApplication::print);
}
}
public void print () {
System.out.println(Thread.currentThread().getName() + " : " + number.incrementAndGet());
}
uses AtomicInteger instead of simple int value and lock operations. But order of output may be like this :
pool-1-thread-1 : 1
pool-1-thread-2 : 2
pool-1-thread-1 : 3
pool-1-thread-1 : 4
pool-1-thread-2 : 5
pool-1-thread-2 : 7
pool-1-thread-1 : 6
pool-1-thread-2 : 8
pool-1-thread-1 : 9
pool-1-thread-2 : 10
It you need order in your output then need to think how to deal with it.

Print timed thread

I'm working on the following assignment:
Consider a shared counter whose values are non-negative integers,
initially zero. A time-printing thread increments the counter by one
and prints its value each second from the start of execution. A
message-printing thread prints a message every fifteen seconds. Have
the message-printing thread be notified by the time-printing thread as
each second passes by. Add another message-printing thread that prints
a different message every seven seconds. Such addition must be done
without modifying the time-printing thread implementation.
Have all involved threads share the counter object that is updated by
the time-printing thread every second. The time-printing thread will
notify other threads to read the counter object each time it updates
the counter, then each message-printing thread will read the counter
value and see if its assigned time period has elapsed; if so, it will
print its message.
import java.lang.Class;
import java.lang.Object;
public class Main2 {
public static void main(String... args)
{
Thread thread = new Thread()
{
public void run()
{
int x = 0;
while(true)
{
x = x + 1;
System.out.print(x + " ");
if(x%7 == 0)
{
System.out.println();
System.out.println("7 second message");
}
if(x%15 == 0)
{
System.out.println();
System.out.println("15 second message");
}
try { Thread.sleep(1000); }
catch (Exception e) { e.printStackTrace(); }
}
}
};
thread.start();
}
}
This outputs what I want it to, but the requirement calls for multiple threads to output when the 7 and 15 second messages show. I can't wrap my head around how to use multiple threads to do this.
You have to remove the ";" after if conditions.
if(x%7 == 0);
and
if(x%15 == 0);
Check the following code
public static void main(String... args) {
Thread thread = new Thread() {
public void run() {
int x = 0;
while (true) {
x = x + 1;
System.out.print(x + " ");
if (x % 7 == 0)
{
System.out.println();
System.out.println("7 second message");
}
if (x % 15 == 0)
{
System.out.println();
System.out.println("15 second message");
}
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
thread.start();
}
My output for this as follows
1 2 3 4 5 6 7
7 second message
8 9 10 11 12 13 14
7 second message
15
15 second message
16 17 18 19 20 21
7 second message
22 23 24 25 26 27 ...

Print 1 to 100 using 10 threads in java

I'm new to muti-threading and I got a question to print 1 to 100 using 10 threads in Java with below constrain.
Thread t1 should print:
1, 11, 21, 31, ... 91
t2 should print:
2, 12, 22, 32, ... 92
likewise
t10 should print:
10, 20, 30, ... 100
The final output should be
1 2 3 .. 100
I have tried it, but it is throwing the following exception in all 10 threads:
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at thread.run(MyThread.java:58)
at java.lang.Thread.run(Unknown Source)
Please let me know how I can solve this problem.
public class MyThread {
/**
* #param args
*/
public static void main(String[] args) {
thread.setSequence();
for(int i = 1; i <= 10; i++) {
Thread t = new Thread(new thread(i));
t.setName(i + "");
t.start();
}
}
}
class thread implements Runnable {
private static HashMap< String, String> sequence = new HashMap<String, String>();
public static final Object lock = new Object();
public static String turn = "1";
private int startValue = 0;
private AtomicInteger counter = new AtomicInteger(1);
public thread(int startValue){
this.startValue = startValue;
}
#Override
public void run() {
while (!counter.equals(10)){
synchronized (lock) {
if(Thread.currentThread().getName().equals(turn)){
System.out.print(startValue + " ");
startValue += 10;
counter.incrementAndGet();
turn = getNextTurn(turn);
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
}
}
}
public static void setSequence(){
for (int i = 1; i <= 10; i++)
if (i == 10)
sequence.put(i + "", 1 + "");
else
sequence.put(i + "", (i + 1) + "");
}
public static String getNextTurn(String currentTurn){
return sequence.get(currentTurn);
}
}
The simplest way would be to have a volatile variable from which each thread reads in and update according to its turn, otherwise it just waits until his turn. When counter is equals to 100 you stop all threads to run by breaking the outer loop.
class MyRunnable implements Runnable {
private static final int LIMIT = 20;
private static volatile int counter = 0;
private int id;
public MyRunnable(int id) {
this.id = id;
}
#Override
public void run() {
outer:
while(counter < LIMIT) {
while (counter % NB_THREADS != id) {
if(counter == LIMIT) break outer;
}
System.out.println("Thread "+Thread.currentThread().getName()+ " printed " + counter);
counter += 1;
}
}
}
Given a LIMIT of 20 and 10 threads, it outputs:
Thread 0 printed 0
Thread 1 printed 1
Thread 2 printed 2
Thread 3 printed 3
Thread 4 printed 4
Thread 5 printed 5
Thread 6 printed 6
Thread 7 printed 7
Thread 8 printed 8
Thread 9 printed 9
Thread 0 printed 10
Thread 1 printed 11
Thread 2 printed 12
Thread 3 printed 13
Thread 4 printed 14
Thread 5 printed 15
Thread 6 printed 16
Thread 7 printed 17
Thread 8 printed 18
Thread 9 printed 19
Of course, this is a very bad usage of multithreading because each thread waits its turn to print and increment the counter.
Multithreading works well when threads can work independently of another for relatively long time's window, and then may occasionally meet up to compare or combine their results if needed.
For example in the fork-join model, each thread does its task independently then their results are merged to produce the final outcome, such as in a merge sort for example. But this assume that the task can be easily parallelizable into independant subtasks, which is not the case here because your final output should be consecutive numbers.
So here a simple loop would be largely more efficient, but I can understand it's for learning purposes.
Here is a solution for the problem.The current thread acquire the lock and we decide if the thread is eligible to execute (printing the number here). If so perform the operation and notify all threads that they can try now. Else wait till its notified by other threads.
public class MyThread extends Thread{
//define the Total No.Of Threads needed
public static final int TOTAL_THREADS = 10;
public final static Object obj = new Object();
int threadNo;
static volatile int counter = 1;
public MyThread(int threadNo){
this.threadNo= threadNo;
}
#Override
public void run(){
//in a synchronized block to acquire lock
synchronized (obj) {
while(counter<=100){
/*
* counter==threadNo => To print the initial numbers till TOTAL_THREADS
* counter%TOTAL_THREADS == threadNo => e.g 11%10 = 1 -> 1 will print this, 12%10 = 2 ..
* (counter%TOTAL_THREADS == 0) && (TOTAL_THREADS == threadNo) => 10%10 will be 0,
* and this must be printed by 10 th thread only, ie the highest thread.
*/
if(counter == threadNo || (counter%TOTAL_THREADS == threadNo) ||
((counter%TOTAL_THREADS == 0) && (TOTAL_THREADS == threadNo))){
//Display the output as desired
System.out.println(this.threadNo+" printing"+" "+counter++);
//notify
obj.notifyAll();
}else{
//current thread not eligible for printing the current counter value, so wait till its notified
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main (String args[]) {
/*
* Creating as many threads as needed.
*/
for(int i = 1; i<=TOTAL_THREADS;i++){
MyThread th = new MyThread(i);
th.start();
}
}
}
The output will be
1 printing 1,
2 printing 2,
3 printing 3,
4 printing 4,
5 printing 5,
6 printing 6,
7 printing 7,
8 printing 8,
9 printing 9,
10 printing 10,
1 printing 11,
2 printing 12,
3 printing 13,
4 printing 14,
...
7 printing 97,
8 printing 98,
9 printing 99,
10 printing 100
Hope this helps =) Took me an hour to do it.
package com.xxxx.simpleapp;
import java.util.ArrayList;
import java.util.List;
public class TenThreads {
public int currentTaskValue = 1;
public static void main(String[] args) {
TenThreads monitor = new TenThreads();
List<ModThread> list = new ArrayList();
for (int i = 0; i < 10; i++) {
ModThread modThread = new ModThread(i, monitor);
list.add(modThread);
}
for (ModThread a : list) {
a.start();
}
}
}
class ModThread extends Thread {
private int modValue;
private TenThreads monitor;
public ModThread(int modValue, TenThreads monitor) {
this.modValue = modValue;
this.monitor = monitor;
}
#Override
public void run() {
synchronized (monitor) {
try {
while (true) {
while (monitor.currentTaskValue % 10 != modValue) {
monitor.wait();
}
if (monitor.currentTaskValue == 101) {
break;
}
System.out.println(Thread.currentThread().getName() + " : "
+ monitor.currentTaskValue + " ,");
monitor.currentTaskValue = monitor.currentTaskValue + 1;
monitor.notifyAll();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
output
Thread-1 : 1 ,
Thread-2 : 2 ,
Thread-3 : 3 ,
Thread-4 : 4 ,
Thread-5 : 5 ,
Thread-6 : 6 ,
Thread-7 : 7 ,
Thread-8 : 8 ,
Thread-9 : 9 ,
......
.....
...
Thread-4 : 94 ,
Thread-5 : 95 ,
Thread-6 : 96 ,
Thread-7 : 97 ,
Thread-8 : 98 ,
Thread-9 : 99 ,
Thread-0 : 100 ,
Documentation are intentionally left out for you to figure it out, there are minor bugs too!
Error is thrown due to calling of wait not on proper object. wait() should be called on object on which lock is acquired, the one implied by synchronized keyword.
Well I do not have the code...but the perspective seems to be
that there are 100 tasks to be executed each of incrementing
a count by 1.
So there could be a ThreadPool of say 10 threads and these
threads are incrementing the shared count value...
Only point to consider is that the Thread pools worker threads
have to sequentially execute their tasks one after the other
and the thread sequence for the 10 have to be maintained...
One simple way to solve this is use below state in runnable class
private final int index;
private final AtomicInteger atomicInteger;
private final CyclicBarrier cyclicBarrier;
index - is responsible for conditional verification i.e., which number this thread should print.
atomicInteger - shared across all threads for current number.
Cyclic barrier - makes all threads to wait unit a every thread completes a cycle/iteration.
Code sample:
public class PrintSequence {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
final AtomicInteger atomicInteger = new AtomicInteger(1);
final CyclicBarrier cyclicBarrier = new CyclicBarrier(10, ()-> {
System.out.println("a cycle done");
});
IntStream.rangeClosed(0, 9)
.boxed()
.map(i -> new PrintSequenceTask(i, atomicInteger, cyclicBarrier))
.map(p -> executorService.submit(p))
.collect(Collectors.toList());
executorService.shutdown();
}
}
class PrintSequenceTask implements Runnable {
private final int index;
private final AtomicInteger atomicInteger;
private final CyclicBarrier cyclicBarrier;
PrintSequenceTask(int index, AtomicInteger atomicInteger, CyclicBarrier cyclicBarrier) {
this.index = index;
this.atomicInteger = atomicInteger;
this.cyclicBarrier = cyclicBarrier;
}
#Override
public void run(){
for(int i=1; i<10;i++){
while (((atomicInteger.get()-index-1)%10 != 0)){}
System.out.println(Thread.currentThread().getName()+" "+(atomicInteger.get()));
atomicInteger.getAndIncrement();
await();
}
}
public void await(){
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
public class BigSequence {
public static void main(String[] args) {
BigPrintNum p = new BigPrintNum();
int max = 20;
int no_threads = 11;
for(int i=0;i<no_threads;i++){
boolean b[] = new boolean[no_threads];
b[i] = true;
Thread t = new Thread(new BigPrint(p, max, b,no_threads));
t.start();
}
}
}
class BigPrint implements Runnable {
int num=0;
BigPrintNum p;
int max;
int no_threads;
boolean b[];
public BigPrint(BigPrintNum p,int max,boolean b[],int no_threads){
this.p = p;
this.max = max;
this.b = b;
this.no_threads = no_threads;
}
#Override
public void run() {
int n = 0;
for(int i=0;i<no_threads;i++){
if(b[i] == true){
n = i;
num = i;
}
}
while(num<=max){
p.print(num, n, no_threads);
num += no_threads;
}
}
}
class BigPrintNum {
int turn = 0;
public synchronized void print(int n,int i,int no_threads){
while(this.turn != i){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println(i + "th seq = " + n);
this.turn = (i+1)%no_threads;
notifyAll();
}
}
Its a generic one, where we can use any number of threads and use any max value.
public class ThreadSequence
{
public static int totalThread;
public static void main(String[] args)
{
MyLock myLock = new MyLock();
totalThread = 10;
for(int i=1;i<=totalThread;i++)
{
MyThread myThread = new MyThread(i,myLock);
myThread.start();
}
}
}
class MyLock
{
public int counter = 0;
}
MyThread Class
class MyThread extends Thread{
public MyLock lock;
public int no;
public MyThread(int no,MyLock lock)
{
super("My Thread No "+no);
this.no = no;
this.lock = lock;
}
public void run()
{
synchronized (lock)
{
while(true)
{
while(lock.counter%ThreadSequence.totalThread !=(this.no-1))
{
try
{
if(lock.counter > 99)
{
break;
}
lock.wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
if(lock.counter > 99)
{
break;
}
System.out.println("Current Thread "+Thread.currentThread().currentThread()+" --- Current Count "+(lock.counter+1));
lock.counter = lock.counter +1 ;
lock.notifyAll();
}
}
}
}
print 1 to 100 number alternatively by each thread similar way you can print for 10 threads- m1 and m2 like
m1-1
m2-2
m3-3
m4-4
public class MultiThread extends Thread {
static volatile int num=0;
public static void main(String[] args) {
MultiThread m1= new MultiThread();
MultiThread m2= new MultiThread();
m1.setName("m1");
m1.setPriority(5);
m2.setName("m2");
m2.setPriority(5);
m1.start();
m2.start();
}
#Override
public void run() {
while(num<100) {
num +=1;
print();
}
}
private void print(){
synchronized(this) {
System.out.println(currentThread().getName()+" "+ num);
try {
currentThread().wait(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
The simple thing to do is to hold common resource for all of them.
Hold a List and every thread will insert into the list, in the end you can sort and print..
If you want them to do it on your order it won't be very effective because you won't need 10 threads to do it..
This way it will be faster and will use 10 threads to do some work, but when everyone finish you still need to do some work
public class PrintNumbersbyThreads implements Runnable {
private int i;
public PrintNumbersbyThreads(int i) {
this.i = i;
}
public static void main(String[] args) {
PrintNumbersbyThreads p = new PrintNumbersbyThreads(1);
PrintNumbersbyThreads p2 = new PrintNumbersbyThreads(2);
PrintNumbersbyThreads p3 = new PrintNumbersbyThreads(3);
Thread t1 = new Thread(p, "t1");
Thread t2 = new Thread(p2, "t2");
Thread t3 = new Thread(p3, "t3");
t1.start();
try {
t1.join();
t2.start();
t2.join();
t3.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void run() {
System.out.println("\n" + Thread.currentThread().getName() + " prints ");
for (int j = 0; j < 10; j++) {
System.out.print(i + " ");
i = i + 10;
}
}
}
Written sample code 3 Threads and the output is
t1 prints:
1 11 21 31 41 51 61 71 81 91
t2 prints:
2 12 22 32 42 52 62 72 82 92
t3 prints:
3 13 23 33 43 53 63 73 83 93
Hope this is what you are Looking for?
I have written one generic code which will take the number till where you want to print and the number of threads to be used.
public class ThreadedPrinting {
private Object locks[];
private static class Printer extends Thread {
int curVal;
int endVal;
Object myLock;
Object nextLock;
int step;
public Printer(int startFrom, int endVal, int step, Object myLock, Object nextLock){
this.curVal = startFrom;
this.endVal = endVal;
this.step = step;
this.myLock = myLock;
this.nextLock = nextLock;
this.step = step;
}
#Override
public void run(){
synchronized(myLock) {
while (curVal <= endVal) {
try {
myLock.wait();
System.out.println(curVal);
curVal += step;
}
catch(InterruptedException e) {}
synchronized(nextLock) {
nextLock.notify();
}
}
}
synchronized(nextLock) {
nextLock.notify(); /// this ensures all worker threads exiting at the end
}
}
} // Printer
public ThreadedPrinting(int maxNum, int threads) {
locks = new Object[threads];
int i;
for(i = 0; i < threads; ++i) locks[i] = new Object();
for(i = 0; i < threads -1 ; ++i) {
Printer curPrinter = new Printer(i, maxNum, threads, locks[i], locks[i+1]);
curPrinter.start();
}
Printer lastPrinter = new Printer(i, maxNum, threads, locks[threads - 1], locks[0]);
lastPrinter.start();
}
public void start() {
synchronized (locks[0]) {
locks[0].notify();
}
}
public static void main(String[] args) {
ThreadedPrinting printer = new ThreadedPrinting(1000,7);
printer.start();
}
}
The same problem can be solved by usign Phaser as well but the order is not restrictive but will be in round-robin fashion. I have provided the solution for similar problem here.

Wait for one thread to finish in java

I am relatively new Threading in java and I was trying to do the following work. Two Threads will run. Thread1 will print from 1-10 and then wait while Thread2 will finish printing 11-20 and then finishes its task and notify thread1 to print 21-30 and then thread1 will terminate as well.
This is the code I have used:
private Thread thread = null;
private String name = null;
private static Object obj = new Object();
private static int index = 1;
public childThread(Thread t, String name)
{
this.name = name;
this.thread = t;
}
public void run()
{
try
{
while (true) {
Thread.sleep(500);
if (index % 10 == 0 && index == 10) {
System.out.println("Waiting for Thread2");
synchronized (obj) {
obj.notify();
obj.wait();
}
}
else if (index % 10 == 0 && index == 20) {
System.out.println("Waiting for Thread1");
synchronized (obj) {
obj.notify();
obj.wait();
}
}
else if(index == 30)
{
obj.wait();
}
synchronized (obj) {
System.out.println(name + " ><>< " + index);
index++;
}
}
}
catch(Exception e)
{
}
And I am getting the following output:
Thread2 ><>< 1
Thread1 ><>< 2
Thread2 ><>< 3
Thread1 ><>< 4
Thread2 ><>< 5
Thread1 ><>< 6
Thread1 ><>< 7
Thread2 ><>< 8
Thread2 ><>< 9
Thread1 ><>< 10
Thread2 ><>< 11
Thread1 ><>< 12
Thread2 ><>< 13
Thread1 ><>< 14
Thread2 ><>< 15
Thread1 ><>< 16
Thread2 ><>< 17
Thread1 ><>< 18
Thread2 ><>< 19
Waiting for Thread1
Waiting for Thread1
Thread1 ><>< 20
Thread1 ><>< 21
Thread1 ><>< 22
Thread1 ><>< 23
Thread1 ><>< 24
Thread1 ><>< 25
Thread1 ><>< 26
Thread1 ><>< 27
Thread1 ><>< 28
Thread1 ><>< 29
Based on my current understanding in Java threading.
if(index %10 == 0 && index == 10) block will notify the other thread to run and wait while the other completed and same goes for the second one. Now it does not work first time. But when index == 20, thread2 stops working and thread1 continue to print30.
Thanks for your help. :)
The fundamental problem here is that you've got a race condition where both threads enter the loop at the same time.
You need to arrange it such that only one is allowed in and the other has to wait immediately.
You might instead try a loop like the following, which is mutually exclusive. One thread will be allowed to enter and begin incrementing and the other has to stop until the first thread calls obj.wait().
synchronized(obj) {
while (index < 30) {
Thread.sleep(500);
if (index > 0 && index % 10 == 0) {
obj.notify();
obj.wait();
}
index++;
}
}
I have wrote one simple code using Shared Objected Class named Counter which will track counter details and wrote two threads ThreadOne and ThreadTwo and Main application class as given below.
As suggested by other, you can use high level lock object like Semaphore or Lock class.
package thread.communication.demo;
public class Counter {
private int count = 1;
private boolean lockTrue = false;
public synchronized void incrFirstThread() {
while (lockTrue) {
try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(Counter.class.getName()).log(Level.SEVERE, null, ex);
}
}
lockTrue = true;
for (int i = count; i < count + 10; i++) {
System.out.println(i + Thread.currentThread().getName());
}
count += 10;
notifyAll();
}
public synchronized void incrSecondThread() {
while (!lockTrue) {
try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(Counter.class.getName()).log(Level.SEVERE, null, ex);
}
}
lockTrue = false;
for (int i = count; i < count + 10; i++) {
System.out.println(i + Thread.currentThread().getName());
}
count += 10;
notifyAll();
}
}
package thread.communication.demo;
public class ThreadOne extends Thread{
Counter counter;
ThreadOne(Counter counter)
{
this.counter=counter;
}
#Override
public void run() {
while (true) {
counter.incrFirstThread();
}
}
}
package thread.communication.demo;
public class ThreadTwo extends Thread {
Counter counter;
ThreadTwo(Counter counter)
{
this.counter=counter;
}
#Override
public void run() {
while (true) {
counter.incrSecondThread();
}
}
}
package thread.communication.demo;
public class ThreadMain {
public static void main(String[] args) {
Counter counter=new Counter();
ThreadOne one = new ThreadOne(counter);
ThreadTwo two = new ThreadTwo(counter);
one.start();
two.start();
}
}
Output is as given below.
[INFO] [INFO] --- exec-maven-plugin:1.2.1:exec (default-cli) #
MultiThreading ---
1Thread-0 2Thread-0 3Thread-0 4Thread-0 5Thread-0 6Thread-0 7Thread-0
8Thread-0 9Thread-0 10Thread-0 11Thread-1 12Thread-1 13Thread-1
14Thread-1 15Thread-1 16Thread-1 17Thread-1 18Thread-1 19Thread-1
20Thread-1 21Thread-0 22Thread-0 23Thread-0 24Thread-0 25Thread-0
26Thread-0 27Thread-0 28Thread-0 29Thread-0 30Thread-0 31Thread-1
32Thread-1 33Thread-1 34Thread-1 35Thread-1 36Thread-1 37Thread-1
38Thread-1 39Thread-1 40Thread-1 41Thread-0 42Thread-0 43Thread-0
44Thread-0 45Thread-0 46Thread-0 47Thread-0 48Thread-0 49Thread-0
50Thread-0 51Thread-1 52Thread-1 53Thread-1 54Thread-1 55Thread-1
56Thread-1 57Thread-1 58Thread-1 59Thread-1 60Thread-1
This is a working code, hope this helps
public static void main(String[] args) {
final Object lock = new Object();
final Thread t2 = new Thread() {
public void run() {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
for(int i = 11; i < 21; i++) System.out.println(i);
}
};
Thread t1 = new Thread() {
public void run() {
for(int i = 1; i < 11; i++) System.out.println(i);
synchronized (lock) {
lock.notifyAll();
}
try {
t2.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
for(int i = 21; i < 31; i++) System.out.println(i);
}
};
t1.start();
t2.start();
}

Categories