Threads - simple concurrency issue - java

Ok this is the problem: the following code is obviously not written thread safe, cause the method increment() is not syncronized. The output varies, and doesn't go like: 1,2,3,4,5,6...
For example the output can be this: 1,2,3,4,5,1...
but then it continues like this 6,7,8,... and reaches 100. I don't understand how can it reach 100, shouldnt after second 1 come 2 again, at least in some cases, couse the balance was wrongly updated by the other thread. The question is this: why after 1 it continues normally with 6, 7...
class Job implements Runnable{
private int balance;
public void run(){
for (int i = 0; i < 50; i++) {
increment();
System.out.println(balance);
int a = 3;
int b = 4;
a = b;
}
}
public void increment(){
int i = balance;
balance = i+1;
}
}
public class ThreadsDemo{
public static void main(String[] args) {
Job job = new Job();
Thread alpha = new Thread(job);
Thread beta = new Thread(job);
alpha.setName("alpha");
beta.setName("beta");
alpha.start();
beta.start();
}
}
To explain further, here is one of the possible outcomes:
Thread 1:
balance - 0
i - 0 (thread 1 put back to runnable)
Thread 2:
balance - 0, 1, 2, 3, 4, 5
i - 0, 1, 2, 3, 4, (thread 2 put back to runnable)
Thread 1 (put to running):
balance - ... 1, 2
i - 0, 1
(In some cases it can update normaly, but in 50 iterations it must come some abnormal update)
How does every outcome reach 100, is this some IDE optimization to deal with thread interleaving or what?
ANSWER:
So no need for latch in this example, just that the thread was "blocking" on print, and the other could finish the update in the meantime. Ty Affe
class Job implements Runnable{
public int balance = 0;
//public static CountDownLatch latch = new CountDownLatch(1);
public void run(){
for (int i = 0; i < 50000; i++) {
increment();
}
}
public void increment(){
int i = balance;
balance = i+1;
}
}
public class ThreadsDemo{
public static void main(String[] args) {
Job job = new Job();
Thread alpha = new Thread(job);
Thread beta = new Thread(job);
alpha.setName("alpha");
beta.setName("beta");
alpha.start();
beta.start();
try {
alpha.join();
beta.join();
} catch (Exception ex) { }
System.out.println(job.balance +" "+ alpha.isAlive() + " " + beta.isAlive());
}
}
The output is around 60 000, as it was expected.

You calculation is very fast and starting threads is very slow. The first one is completely done before the second one ever begins. The out-of-place numbers in the output are likely just issues with buffer flushing in the operating system.
Add a latch so that both threads actually start at the same time, and use a sufficiently large number, and you will see a total that doesn't add up.
public static CountDownLatch latch = new CountDownLatch(1);
private static class Job implements Runnable{
private int balance;
public void run(){
try {
latch.await();
} catch (InterruptedException e) {}
for (int i = 0; i < 50000; i++) {
//existing code
}
}
public void increment(){
int i = balance;
//make it work harder so there's more opportunity for an actual interleave
balance = new BigInteger(Integer.toString(i)).add(BigInteger.ONE).intValue();
}
}
public static void main(String[] args) {
//existing code
alpha.start();
beta.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
latch.countDown();
}

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

How can I schedule some work in n threads separately

Lets say I have n threads concurrently taking values from a shared queue:
public class WorkerThread implements Runnable{
private BlockingQueue queue;
private ArrayList<Integer> counts = new ArrayList<>();
private int count=0;
public void run(){
while(true) {
queue.pop();
count++;
}
}
}
Then for each thread, I want to count every 5 seconds how many items it has dequeued, and then store it in its own list (counts)
I've seen here Print "hello world" every X seconds how you can run some code every x seconds:
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask(){
#Override
public void run(){
counts.add(count);
count = 0
}
}, 0, 5000);
The problem with this is that I can't access count variable and the list of counts unless they are static. But I don't want them to be static because I don't want the different threads to share those variables.
Any ideas of how to handle this?
I don't think it's possible to use scheduled execution for you case(neither Timer nor ScheduledExecutorService), because each new scheduled invocation will create a new tasks with while loop. So number of tasks will increase constantly.
If you don't need to access this list of counts in runtime i would suggest something like this one:
static class Task implements Runnable {
private final ThreadLocal<List<Integer>> counts = ThreadLocal.withInitial(ArrayList::new);
private volatile List<Integer> result = new ArrayList<>();
private BlockingQueue<Object> queue;
public Task(BlockingQueue<Object> queue) {
this.queue = queue;
}
#Override
public void run() {
int count = 0;
long start = System.nanoTime();
try {
while (!Thread.currentThread().isInterrupted()) {
queue.take();
count++;
long end = System.nanoTime();
if ((end - start) >= TimeUnit.SECONDS.toNanos(1)) {
counts.get().add(count);
count = 0;
start = end;
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// the last value
counts.get().add(count);
// copy the result cause it's not possible
// to access thread local variable outside of this thread
result = counts.get();
}
public List<Integer> getCounts() {
return result;
}
}
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(3);
BlockingQueue<Object> blockingQueue = new LinkedBlockingQueue<>();
Task t1 = new Task(blockingQueue);
Task t2 = new Task(blockingQueue);
Task t3 = new Task(blockingQueue);
executorService.submit(t1);
executorService.submit(t2);
executorService.submit(t3);
for (int i = 0; i < 50; i++) {
blockingQueue.add(new Object());
Thread.sleep(100);
}
// unlike shutdown() interrupts running threads
executorService.shutdownNow();
executorService.awaitTermination(1, TimeUnit.SECONDS);
System.out.println("t1 " + t1.getCounts());
System.out.println("t2 " + t2.getCounts());
System.out.println("t3 " + t3.getCounts());
int total = Stream.concat(Stream.concat(t1.getCounts().stream(), t2.getCounts().stream()), t3.getCounts().stream())
.reduce(0, (a, b) -> a + b);
// 50 as expected
System.out.println(total);
}
Why not a static AtomicLong?
Or the WorkerThread(s) can publish that they poped to the TimerTask or somewhere else? And the TimerTask reads that info?

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.

How to remove manually created pauses in Main-thread?

Problem description:
We have a given matrix randomly filled with digits and have to create separate threads for each row of the matrix that count how many times the digits encounter in that row.
Without these sleeps in the main thread, it's not working correctly..
Here's my solution.
Also it's following here:
public class TestingMatrixThreads {
public static void main(String[] arr) throws InterruptedException {
int[][] a = new int[67][6];
// class.Count works with class.Matrix, that's why I've made it this way
Matrix m = new Matrix(a);
m.start();
Thread.sleep(1000); // Here comes the BIG question -> how to avoid these
// manually created pauses
Count c;
Thread t;
// Creating new threads for each row of the matrix
for (int i = 0; i < Matrix.matr.length; i++) {
c = new Count(i);
t = new Thread(c);
t.start();
}
//Again - the same question
System.out.println("Main - Sleep!");
Thread.sleep(50);
System.out.println("\t\t\t\t\tMain - Alive!");
int sum = 0;
for (int i = 0; i < Count.encounters.length; i++) {
System.out.println(i + "->" + Count.encounters[i]);
sum += Count.encounters[i];
}
System.out.println("Total numbers of digits: " + sum);
}
}
class Count implements Runnable {
int row;
public static int[] encounters = new int[10]; // here I store the number of each digit's(array's index) encounters
public Count(int row) {
this.row = row;
}
public synchronized static void increment(int number) {
encounters[number]++;
}
#Override
public void run() {
System.out.println(Thread.currentThread().getName() + ", searching in row " + row + " STARTED");
for (int col = 0; col < Matrix.matr[0].length; col++) {
increment(Matrix.matr[row][col]);
}
try {
Thread.sleep(1); // If it's missing threads are starting and stopping consequently
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + " stopped!");
}
}
class Matrix extends Thread {
static int[][] matr;
public Matrix(int[][] matr) {
Matrix.matr = matr;
}
#Override
public void run() {
//print();
fill();
System.out.println("matrix filled");
print();
}
public static void fill() {
for (int i = 0; i < matr.length; i++) {
for (int j = 0; j < matr[0].length; j++) {
matr[i][j] = (int) (Math.random() * 10);
}
}
}
public static void print() {
for (int i = 0; i < matr.length; i++) {
for (int j = 0; j < matr[0].length; j++) {
System.out.print(matr[i][j] + " ");
}
System.out.println();
}
}
}
P.S. I'm sorry if this question is too stupid for you to answer, but I'm a newbie in Java programming, as well as it's my very first post in stackoverflow, so please excuse me for the bad formatting, too :)
Thank you in advance!
Change the Thread.sleep by m.join()
Doing this will make the main thread wait for the other to complete its work and then it will continu its execution.
Cheers
To answer your main question:
Thread.join();
For example:
public static void main(String[] args) throws Exception {
final Thread t = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Do stuff");
}
});
t.start();
t.join();
}
The start call, as you know, kicks off the other Thread and runs the Runnable. The join call then waits for that started thread to finish.
A more advanced way to deal with multiple threads is with an ExecutorService. This detaches the threads themselves from the tasks they do. You can have a pool of n threads and m > n tasks.
Example:
public static void main(String[] args) throws Exception {
final class PrintMe implements Callable<Void> {
final String toPrint;
public PrintMe(final String toPrint) {
this.toPrint = toPrint;
}
#Override
public Void call() throws Exception {
System.out.println(toPrint);
return null;
}
}
final List<Callable<Void>> callables = new LinkedList<>();
for (int i = 0; i < 10; ++i) {
callables.add(new PrintMe("I am " + i));
}
final ExecutorService es = Executors.newFixedThreadPool(4);
es.invokeAll(callables);
es.shutdown();
es.awaitTermination(1, TimeUnit.DAYS);
}
Here we have 4 threads and 10 tasks.
If you go down this route you probably need to look into the Future API to so that you can check whether the tasks completed successfully. You can also return a value from the task; in your case a Callable<Integer> would seem to be appropriate so that you can return the result of your calculation from the call method and gather up the results from the Future.
As other Answers have stated, you can do this simply using join; e.g.
Matrix m = new Matrix(a);
m.start();
m.join();
However, I just want to note that if you do that, you are not going to get any parallelism from the Matrix thread. You would be better of doing this:
Matrix m = new Matrix(a);
m.run();
i.e. executing the run() method on the main thread. You might get some parallelism by passing m to each "counter" thread, and having them all join the Matrix thread ... but I doubt that it will be worthwhile.
Frankly, I'd be surprised if you get a worthwhile speedup for any of the multi-threading you are trying here:
If the matrix is small, the overheads of creating the threads will dominate.
If the matrix is large, you are liable to run into memory contention issues.
The initialization phase takes O(N^2) computations compared with the parallelized 2nd phase that has N threads doing O(N) computations. Even if you can get a decent speedup in the 2nd phase, the 1st phase is likely to dominate.

Thread Scheduling - Shared Array

I need two threads to write one a shared array of ints. Both threads need to write on all the elements of that array. Each thread will write either 1 or 7, and the result should be like 171717171 (or 71717171). To do that I have the first Thread1 write at position 0, then wait. Thread2 now writes at position 0 and 1, notifies Thread1, and waits. Thread1 writes at position 1 and 2, notifies Thread2 and waits, etc. With the following code I get correct output, although when run with JPF it finds a deadlock. Its become really frustrating since I can not find whats wrong with it. Any advice would be appreciated.
import java.util.logging.Level;
import java.util.logging.Logger;
public class WriterThreadManager {
private int[] array = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
private Thread thread7;
private Thread thread1;
public static void main(String[] args) {
WriterThreadManager mng = new WriterThreadManager();
mng.exec();
}
public WriterThreadManager() {
thread7 = new Thread(new WriterRunnable(this, 7));
thread1 = new Thread(new WriterRunnable(this, 1));
}
public void overwriteArray(int pos, int num) {
array[pos] = num;
printArray();
}
private void printArray() {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]);
}
System.out.println("");
}
public synchronized void stopThread() {
try {
this.wait();
} catch (InterruptedException ex) {
Logger.getLogger(WriterThreadManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
public synchronized void wakeUpThread() {
notifyAll();
}
private void exec() {
thread7.start();
thread1.start();
}
public int length() {
return array.length;
}
}
public class WriterRunnable implements Runnable {
private WriterThreadManager mng;
private int numberToWrite;
private static boolean flag = true;
#Override
public void run() {
int counter = 0;
int j = 0;
//first thread to get in should write only at
//position 0 and then wait.
synchronized (mng) {
if (flag) {
flag = false;
mng.overwriteArray(0, numberToWrite);
j = 1;
waitForOtherThread();
}
}
for (int i = j; i < mng.length(); i++) {
mng.overwriteArray(i, numberToWrite);
counter++;
if (i == mng.length() - 1) {
mng.wakeUpThread();
break;
}
if (counter == 2) {
waitForOtherThread();
counter = 0;
}
}
}
private void waitForOtherThread() {
mng.wakeUpThread();
mng.stopThread();
}
public WriterRunnable(WriterThreadManager ar, int num) {
mng = ar;
numberToWrite = num;
}
}
p.s: an example of the execution:
1000000000
7000000000
7700000000
7100000000
7110000000
7170000000
7177000000
7171000000
7171100000
7171700000
7171770000
7171710000
7171711000
7171717000
7171717700
7171717100
7171717110
7171717170
7171717177
7171717171
The error snapshot from JPF is the following:
thread java.lang.Thread:{id:1,name:Thread-1,status:WAITING,priority:5,lockCount:1,suspendCount:0}
waiting on: WriterThreadManager#152
call stack:
at java.lang.Object.wait(Object.java)
at WriterThreadManager.stopThread(WriterThreadManager.java:43)
at WriterRunnable.waitForOtherThread(WriterRunnable.java:53)
at WriterRunnable.run(WriterRunnable.java:45)
thread java.lang.Thread:{id:2,name:Thread-2,status:WAITING,priority:5,lockCount:1,suspendCount:0}
waiting on: WriterThreadManager#152
call stack:
at java.lang.Object.wait(Object.java)
at WriterThreadManager.stopThread(WriterThreadManager.java:43)
at WriterRunnable.waitForOtherThread(WriterRunnable.java:53)
at WriterRunnable.run(WriterRunnable.java:45)
I believe the race is due to this method:
private void waitForOtherThread() {
mng.wakeUpThread();
mng.stopThread();
}
While the individual wakeUpThread() and stopThread() methods are synchronized, you have the opportunity for unexpected thread scheduling between these calls.
Consider:
thread7 - notify thread1 to wakup
thread1 - wake up
thread1 - work to completion
thread1 - notify thread7 to wakeup
thread1 - wait to be notified to wakeup
thread7 - wait to be notified to wakeup
In this case you have deadlocked because thread1 sent its notifyAll() before thread7 had a chance to wait() for it.
Running in a different context can mess with your timing and cause these types of behaviors to appear.
To avoid this I suggestion doing this:
private void waitForOtherThread() {
synchronized(mng) {
mng.wakeUpThread();
mng.stopThread();
}
}
Or better yet, use a semaphore as #KumarVivekMitra suggested. Semaphores combine both the notification system and a counter so that the order of the notify and wait don't matter.
- I think a better approach here would be java.util.Semaphores, which will help you to decide the access over the objects resources by specific numbers of threads at a time.
- Well you can also use the SingleThreadExecutor to solve this, which starts and completes a task before moving on to the 2nd task, so there will be No need of synchronization needed here from your side.
I don't think you need any sort of coordination here. Just have one thread write the even locations and the other thread write the odd locations. Let them both go as fast as they can. Done!

Categories