Parallel task with synchronized arraylist - java

My homework was to create project using parallelization that all should be proper.
However, I made my project but my profesor mentioned something is wrong in my code "please look at array list, something is not ok, maybe synchronization?".
I would like ask you community to help me and point what could be wrong. I think it might be problem with not covering by synchronize brackets my array list, am I right?
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* My project finds all dividors for specific number
*It must use threads, so I made them. First I start them (first loop)
*then join them (second loop). My project must have that loops.
*Problem might be with not synchronizing methods array list...
*/
public class Main {
private final static int NUMBER = 100;
private final static List<Integer> dividors = new ArrayList<Integer>();
public static void main(String[] args) {
new Main().doStuff();
}
private int sqr;
private int sqrp1;
private void doStuff() {
sqr = (int) Math.sqrt(NUMBER);
sqrp1 = sqr + 1;
Thread[] t = new Thread[sqrp1];
//starting tasks
for (int i = 1; i < sqrp1; i++) {
final int it = i;
if (NUMBER % i == 0) {
final int e = i;
t[i] = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("sta"+e);
if (!checkContains(e)) {
addElement(e);
}
final int dividednumber = NUMBER / e;
if (!checkContains(dividednumber)) {
addElement(dividednumber);
}
}
});
t[i].start();
}
}
//calling join for tasks
for (int i = 1; i < sqrp1; i++) {
final int it = i;
if (NUMBER % i == 0) {
try {
System.out.println("sto"+i);
t[i].join();
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
System.out.println("xxx");
Collections.sort(dividors);
Integer[] arrayDividors = dividors.toArray(new Integer[0]);
for (int i = 0; i < arrayDividors.length; i++) {
System.out.println(arrayDividors[i]);
}
}
private synchronized void addElement(int element) {
dividors.add(element);
}
private synchronized boolean checkContains(int element) {
return dividors.contains(element);
}
}
Am I right changing this part, is it ok now?
t[i] = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("waiting " + e);
synchronized (this) {
System.out.println("entering " + e);
if (!checkContains(e)) {
addElement(e);
}
final int dividednumber = NUMBER / e;
if (!checkContains(dividednumber)) {
addElement(dividednumber);
}
System.out.println("leaving " + e);
}
}
});

You need to turn this into a single atomic operation.
if (!checkContains(dividednumber)) {
addElement(dividednumber);
}
Imagine you have two threads.
T1: if (!checkContains(dividednumber)) { // false
T2: if (!checkContains(dividednumber)) { // false
T1: addElement(dividednumber); // adds number
T2: addElement(dividednumber); // adds same number
If you have one addElementWithoutDuplicates, this won't happen.

Related

How to consume in Producer-Consumer using Semphores?

I am trying out the Producer-Consumer problem using Semaphore. The program looks fine to me except for one place.
public class ProducerConsumerWithSemaphores
{
private final ArrayList<Integer> list = new ArrayList<>(5);
private final Semaphore semaphoreProducer = new Semaphore(1);
private final Semaphore semaphoreConsumer = new Semaphore(0);
private void produce() throws InterruptedException
{
for(int i = 0;i< 5;i++)
{
semaphoreProducer.acquire();
list.add(i);
System.out.println("Produced: " + i);
semaphoreConsumer.release();
}
}
private void consumer() throws InterruptedException
{
while (!list.isEmpty()) /// This line is where I have the doubt
{
semaphoreConsumer.acquire();
System.out.println("Consumer: " + list.remove(list.size()-1));
semaphoreProducer.release();
Thread.sleep(100);
}
}
public static void main(String[] args)
{
final ProducerConsumerWithSemaphores obj = new ProducerConsumerWithSemaphores();
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
obj.produce();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
obj.consumer();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}).start();
}
}
Is it okay to check the list if it is not empty before acquiring the semaphore? Will this cause any problem in multithreaded environment?
private void consumer() throws InterruptedException
{
while (!list.isEmpty()) /// This line is where I have the doubt
The problem is, if consumer runs faster than producer, your consumer quit immediately, then you have no consumer!!
The correct example looks like,
Producer–consumer problem#Using semaphores. I believe your intention is not to use true as endless loop because you want Producer/Consumer to quit when job is done. If that's your intention, you can 1. set a totalCount to end the loop. 2. Or a boolean flag which will be set by producer after putItemIntoBuffer when producer put the last one. The flag must be protected as well as the buffer.(update: this method doesn't work if there's multiple producers/consumers) 3. Simulate EOF ( idea taken from producer - consume; how does the consumer stop?)
Will this cause any problem in multithreaded environment?
Your critical section (your list) is not protected . Usually we use 3 semaphores. The 3rd one is used as a mutex to protect the buffer.
To stop producers/consumers,
Example code with method 1:
public class Test3 {
private Semaphore mutex = new Semaphore(1);
private Semaphore fillCount = new Semaphore(0);
private Semaphore emptyCount = new Semaphore(3);
private final List<Integer> list = new ArrayList<>();
class Producer implements Runnable {
private final int totalTasks;
Producer(int totalTasks) {
this.totalTasks = totalTasks;
}
#Override
public void run() {
try {
for (int i = 0; i < totalTasks; i++) {
emptyCount.acquire();
mutex.acquire();
list.add(i);
System.out.println("Produced: " + i);
mutex.release();
fillCount.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
private final int totalTasks;
Consumer(int totalTasks) {
this.totalTasks = totalTasks;
}
#Override
public void run() {
try {
for (int i = 0; i < totalTasks; i++) {
fillCount.acquire();
mutex.acquire();
int item = list.remove(list.size() - 1);
System.out.println("Consumed: " + item);
mutex.release();
emptyCount.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void runTest() {
int numProducer = 3;
int tasksPerProducer = 10;
int numConsumer = 6;
int tasksPerConsumer = 5;
for (int i = 0; i < numProducer; i++) {
new Thread(new Producer(tasksPerProducer)).start();
}
for (int i = 0; i < numConsumer; i++) {
new Thread(new Consumer(tasksPerConsumer)).start();
}
}
public static void main(String[] args) throws IOException {
Test3 t = new Test3();
t.runTest();
}
}
Example code with method 3:
public class Test4 {
private Semaphore mutex = new Semaphore(1);
private Semaphore fillCount = new Semaphore(0);
private Semaphore emptyCount = new Semaphore(3);
private Integer EOF = Integer.MAX_VALUE;
private final Queue<Integer> list = new LinkedList<>(); // need to put/get data in FIFO
class Producer implements Runnable {
private final int totalTasks;
Producer(int totalTasks) {
this.totalTasks = totalTasks;
}
#Override
public void run() {
try {
for (int i = 0; i < totalTasks + 1; i++) {
emptyCount.acquire();
mutex.acquire();
if (i == totalTasks) {
list.offer(EOF);
} else {
// add a valid value
list.offer(i);
System.out.println("Produced: " + i);
}
mutex.release();
fillCount.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
#Override
public void run() {
try {
boolean finished = false;
while (!finished) {
fillCount.acquire();
mutex.acquire();
int item = list.poll();
if (EOF.equals(item)) {
// do not consume this item because it means EOF
finished = true;
} else {
// it's a valid value, consume it.
System.out.println("Consumed: " + item);
}
mutex.release();
emptyCount.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void runTest() {
int numProducer = 3;
int tasksPerProducer = 10;
for (int i = 0; i < numProducer; i++) {
new Thread(new Producer(tasksPerProducer)).start();
}
int numConsumer = numProducer; // producers will put N EOFs to kill N consumers.
for (int i = 0; i < numConsumer; i++) {
new Thread(new Consumer()).start();
}
}
public static void main(String[] args) throws IOException {
Test4 t = new Test4();
t.runTest();
}
}
Instead of using two semaphores why dont you use a single semaphore to such that the synchronization is made between threads link
Additional you can use ArrayBlockingQueue which are thread safe to properly demonstrate the Producer Consumer Problem.

Java - Multithreading with ImageIO

I have a program that loads slowly, which I guess is due to the amount of image resources I have to load at the beginning. I thought multi-threading would help, but now I'm not so sure. Here is my automatic multi-threading method.
private static Thread[] t;
private static int currentThreads;
public static void loadWithThreads(Object[] array, IntegerRunnable r) {
final int threads = Runtime.getRuntime().availableProcessors();
t = new Thread[threads];
for (int i = 0; i < threads; i ++) {
t[i] = new Thread("HMediaConverter") {
final int id = currentThreads;
int items = (array.length / threads) * currentThreads;
#Override
public void run() {
super.run();
for (int i = items; i < (items + (array.length / threads)); i ++) {
r.run(i);
}
//Recycle this thread so it can be used for another time.
try {
t[id].join();
lock.notifyAll();
currentThreads --;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t[i].setPriority(Thread.MAX_PRIORITY);
t[i].start();
currentThreads ++;
}
}
And here is my image loading code:
public static ImageIcon loadImageIcon(String path) {
return new ImageIcon(ImageIO.read(Tools.class.getClassLoader().getResource(path));
}
Surely there is a way to speed things up? I'm running this on a perfectly good Intel i5, it shouldn't be this slow, so it must be my code.
Loading 113 images of a total of 159.14mb with...
public static void loadWithoutThreads(File[] array) {
for (File file : array) {
try {
ImageIO.read(file);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Took ~15s
With...
public static void loadWithThreads(File[] array) {
final int threads = Runtime.getRuntime().availableProcessors();
t = new Thread[threads];
CountDownLatch latch = new CountDownLatch(threads);
for (int i = 0; i < threads; i++) {
t[i] = new Thread("HMediaConverter") {
final int id = currentThreads;
int items = (array.length / threads) * currentThreads;
#Override
public void run() {
try {
System.out.println("Starting " + id);
for (int i = items; i < (items + (array.length / threads)); i++) {
try {
System.out.println(i + ": " + array[i]);
ImageIO.read(array[i]);
} catch (IOException ex) {
ex.printStackTrace();
}
}
} finally {
latch.countDown();
}
}
};
t[i].setPriority(Thread.MAX_PRIORITY);
System.out.println("Start " + i);
t[i].start();
currentThreads++;
}
try {
latch.await();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
took ~11s
With...
public static void loadWithExecutor(File[] images) {
ExecutorService service = Executors.newFixedThreadPool(2);
List<ImageLoadingTask> tasks = new ArrayList<>(images.length);
for (File file : images) {
tasks.add(new ImageLoadingTask(file));
}
try {
List<Future<BufferedImage>> results = service.invokeAll(tasks);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
service.shutdown();
}
public static class ImageLoadingTask implements Callable<BufferedImage> {
private File file;
public ImageLoadingTask(File file) {
this.file = file;
}
#Override
public BufferedImage call() throws Exception {
return ImageIO.read(file);
}
}
Took ~7s
The ExecutorService is more efficient because when one thread is processing a larger file, the other can be processing a number of small files. This is achieved by pooling the threads that aren't doing any work until they are needed, allowing a thread to perform a lot of short work, while the other thread(s) are also busy. You don't need to wait as long
Have a look at Executors for more details
The following is a re-write that should work that is close to what the op wrote. A re-write into A fixed-size thread pool would probably be better.
//import java.util.concurrent.atomic.AtomicInteger;
private static Thread[] t;
private static AtomicInteger completedLoads = new AtomicInteger(0);
public static void loadWithThreads(Object[] array, IntegerRunnable r) {
final int threads = Runtime.getRuntime().availableProcessors();
t = new Thread[threads];
completedLoads = new AtomicInteger(0);
int targetLoads = array.length;
int itemsPerThread = (array.length / threads);
for (int i = 0; i < threads; i ++) {
t[i] = new Thread("HMediaConverter" + i) {
int startItem = itemsPerThread * i;
#Override
public void run() {
super.run();
for (int i = startItem; i < startItem + itemsPerThread; i ++) {
try {
r.run(i);
}
finally {
completedLoads.incrementAndGet();
}
}
}
};
t[i].setPriority(Thread.MAX_PRIORITY);
t[i].start();
}
// Wait for the images to load
while (completedLoads.get() < targetLoads)
{
try {
Thread.sleep(100);
}
catch (InterruptedException ie) {
// ignore
}
}
}
Isolate which part does the slowing down - e.g by running System.currentTimeMillis() btween major segmnst then show us where is the biggest time - or show us all the program.
Threads handling as noted is questionable and you shouldn't use methods such as join etc out of the box unless you have seen it sometwhere provably working.
So post times and we'll take it from there - it could be the images it could be the threads

Multiple threads with notifyAll()

I'm writing a java program that print seconds elapsed, and every 5th second it will print a message. This is a sample output:
0 1 2 3 4 hello 5 6 7 8 9 hello 10 11 12 13 14 hello 15 16 17 18 19 hello
How can I remove the boolean variable printMsg? Is there a better thread design that allow this?
For now, without printMsg the program will print multiple "hello" during the 1/10 second program staying at 5, 10, 15 etc.
class Timer {
private int count = 0;
private int N;
private String msg;
private boolean printMsg = false;
public Timer(String s, int N) {
msg = s;
this.N = N;
}
public synchronized void printMsg() throws InterruptedException{
while (count % N != 0 || !printMsg)
wait();
System.out.print(msg + " ");
printMsg = false;
}
public synchronized void printTime() {
printMsg = true;
System.out.print(count + " ");
count ++;
notifyAll();
}
public static void main(String[] args) {
Timer t = new Timer("hello", 5);
new TimerThread(t).start();
new MsgThread(t).start();
}
}
class TimerThread extends Thread {
private Timer t;
public TimerThread(Timer s) {t = s;}
public void run() {
try {
for(;;) {
t.printTime();
sleep(100);
}
} catch (InterruptedException e) {
return;
}
}
}
class MsgThread extends Thread {
private Timer t;
public MsgThread(Timer s) {t = s;}
public void run() {
try {
for(;;) {
t.printMsg();
}
} catch (InterruptedException e) {
return;
}
}
}
Don't need to use printMsg flag, just notifyAll when count % N == 0
public synchronized void printMsg() throws InterruptedException {
wait();
System.out.print(msg + " ");
}
public synchronized void printTime() {
System.out.print(count + " ");
count++;
if (count % N == 0){
notifyAll();
}
}
One option to simplify and better design is to use single thread instead of two threads. And let the single thread take care of printing seconds as well as message. That way reduce one thread and don't need to wait() and notify. Is there is any reason why you want to use two threads? Code below:
public class Timer {
private int count = 0;
private int N;
private String msg;
public Timer(String s, int N) {
msg = s;
this.N = N;
}
public synchronized void printTime() {
System.out.print(count + " ");
count ++;
if(count % N == 0) {
System.out.print(msg + " ");
}
}
public static void main(String[] args) {
Timer t = new Timer("hello", 5);
new TimerThread(t).start();
}
}
class TimerThread extends Thread {
private Timer t;
public TimerThread(Timer s) {t = s;}
public void run() {
try {
for(;;) {
t.printTime();
sleep(1000);
}
} catch (InterruptedException e) {
return;
}
}
}

3 Threads Printing numbers in sequence

I am trying to write a simple code to print numbers in sequence. Scenario is like
Thread Number
T1 1
T2 2
T3 3
T1 4
T2 5
T3 6
T1 7
T2 8
T3 9
...and so on.
Here is the
public class ThreadNumberPrinter {
Object monitor = new Object();
AtomicInteger number = new AtomicInteger(1);
public static void main(String[] args) {
ThreadNumberPrinter tnp = new ThreadNumberPrinter();
Thread t1 = new Thread(tnp.new Printer(1, 3));
Thread t2 = new Thread(tnp.new Printer(2, 3));
Thread t3 = new Thread(tnp.new Printer(3, 3));
t3.start();
t1.start();
t2.start();
}
class Printer implements Runnable {
int threadId;
int numOfThreads;
public Printer(int id, int nubOfThreads) {
threadId = id;
this.numOfThreads = nubOfThreads;
}
public void run() {
print();
}
private void print() {
try {
while (true) {
Thread.sleep(1000l);
synchronized (monitor) {
if (number.get() % numOfThreads != threadId) {
monitor.wait();
} else {
System.out.println("ThreadId [" + threadId
+ "] printing -->"
+ number.getAndIncrement());
monitor.notifyAll();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
But just after 2nd thread runs and prints the number 2, all thread get into wait stage and nothing gets printed. I am not sure where I am doing wrong.
Any help would be greatly appreciated.
public class TestClass {
private volatile Integer count = 1;
private volatile Integer threadIdToRun = 1;
private Object object = new Object();
public static void main(String[] args) {
TestClass testClass = new TestClass();
Thread t1 = new Thread(testClass.new Printer(1));
Thread t2 = new Thread(testClass.new Printer(2));
Thread t3 = new Thread(testClass.new Printer(3));
t1.start();
t2.start();
t3.start();
}
class Printer implements Runnable {
private int threadId;
public Printer(int threadId) {
super();
this.threadId = threadId;
}
#Override
public void run() {
try {
while (count <= 20) {
synchronized (object) {
if (threadId != threadIdToRun) {
object.wait();
} else {
System.out.println("Thread " + threadId + " printed " + count);
count += 1;
if (threadId == 1)
threadIdToRun = 2;
else if (threadId == 2)
threadIdToRun = 3;
else if (threadId == 3)
threadIdToRun = 1;
object.notifyAll();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Above program gives output
Thread 1 printed 1
Thread 2 printed 2
Thread 3 printed 3
Thread 1 printed 4
Thread 2 printed 5
Thread 3 printed 6
Thread 1 printed 7
Thread 2 printed 8
Thread 3 printed 9
Thread 1 printed 10
Thread 2 printed 11
Thread 3 printed 12
Thread 1 printed 13
Thread 2 printed 14
Thread 3 printed 15
Thread 1 printed 16
Thread 2 printed 17
Thread 3 printed 18
Thread 1 printed 19
Thread 2 printed 20
Well, the problem is that modulo 3 % 3 is 0. Change your threadIds to 0..2 instead of 1..3 and hopefully it should work.
Though this is a bad way for using threads, if we still want it a generic solution can be to have a worker thread which will store its id:
class Worker extends Thread {
private final ResourceLock resourceLock;
private final int threadNumber;
private final AtomicInteger counter;
private volatile boolean running = true;
public Worker(ResourceLock resourceLock, int threadNumber, AtomicInteger counter) {
this.resourceLock = resourceLock;
this.threadNumber = threadNumber;
this.counter = counter;
}
#Override
public void run() {
while (running) {
try {
synchronized (resourceLock) {
while (resourceLock.flag != threadNumber) {
resourceLock.wait();
}
System.out.println("Thread:" + threadNumber + " value: " + counter.incrementAndGet());
Thread.sleep(1000);
resourceLock.flag = (threadNumber + 1) % resourceLock.threadsCount;
resourceLock.notifyAll();
}
} catch (Exception e) {
System.out.println("Exception: " + e);
}
}
}
public void shutdown() {
running = false;
}
}
The ResourceLock class would store flag and max threads count:
class ResourceLock {
public volatile int flag;
public final int threadsCount;
public ResourceLock(int threadsCount) {
this.flag = 0;
this.threadsCount = threadsCount;
}
}
And then main class can use it as below:
public static void main(String[] args) throws InterruptedException {
final int threadsCount = 3;
final ResourceLock lock = new ResourceLock(threadsCount);
Worker[] threads = new Worker[threadsCount];
final AtomicInteger counter = new AtomicInteger(0);
for(int i=0; i<threadsCount; i++) {
threads[i] = new Worker(lock, i, counter);
threads[i].start();
}
Thread.sleep(10000);
System.out.println("Will try to shutdown now...");
for(Worker worker: threads) {
worker.shutdown();
}
}
Here after a certain delay we may like to stop the count and the method shutdown in worker provides this provision.
Below code uses the logic of notifying the next thread to print the number and then incrementing it by 1 and then again notifying the next thread and then go in wait state till some thread notifies it.
Eg. T1 first prints the value and then makes boolean "second" true for T2 to print the next number. T2 after printing the number makes boolean "third" true for T3. T3 does the same thing by making boolean "first" true for T1 to print the next number.
T1 -> T2 -> T3 -> T1 -> T2 -> T3 -> ........ and so on.
public class Test{
public static volatile int i = 0;
public static void main(String[] args) throws InterruptedException {
Object monitor = new Object();
Notifier notifier = new Notifier(monitor);
Thread thread1 = new Thread(notifier, "T1");
Thread thread2 = new Thread(notifier, "T2");
Thread thread3 = new Thread(notifier, "T3");
thread1.start();
thread2.start();
thread3.start();
}
}
class Notifier implements Runnable {
private Object monitor = null;
private static int i = 1;
private static boolean first = true;
private static boolean second = false;
private static boolean third = false;
public Notifier(Object objcurr) {
this.monitor = objcurr;
}
#Override
public void run() {
try {
while (true) {
synchronized (monitor) {
String Tname = Thread.currentThread().getName();
if (first && Tname.equalsIgnoreCase("T1")) {
print();
first = false;
second = true;
monitor.notifyAll();
monitor.wait();
} else if (second && Tname.equalsIgnoreCase("T2")) {
print();
second = false;
third = true;
monitor.notifyAll();
monitor.wait();
} else if (third && Tname.equalsIgnoreCase("T3")) {
print();
third = false;
first = true;
monitor.notifyAll();
monitor.wait();
} else {
monitor.wait();
}
}
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void print() {
System.out.println(Thread.currentThread().getName() + " - " + Notifier.i++);
}
How about this?
public class PrintNumbers implements Runnable {
public static final int NO_OF_THREADS = 3;
public static final int MAX_DIGIT = 20;
public static final String THREAD_NAME_PREFIX = "t";
volatile int current = 1;
private Object lock = new Object();
public static void main(String[] args) {
PrintNumbers printNumbers = new PrintNumbers();
for (int i = 1; i <= NO_OF_THREADS; i++) {
new Thread(printNumbers, THREAD_NAME_PREFIX + i).start();
}
}
#Override
public void run() {
String printThread;
while (current < MAX_DIGIT) {
synchronized (lock) {
if (current % NO_OF_THREADS != 0) {
printThread = THREAD_NAME_PREFIX + current % NO_OF_THREADS;
} else {
printThread = THREAD_NAME_PREFIX + NO_OF_THREADS;
}
if (!printThread.equals(Thread.currentThread().getName())) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (printThread.equals(Thread.currentThread().getName())) {
System.out.println(String.format("Thread %s : %s", Thread.currentThread().getName(), current));
current = current + 1;
}
lock.notifyAll();
}
}
}
}
package com.sourav.mock.Thread;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreeThreadComunication implements Runnable {
AtomicInteger counter;
int[] array;
static final Object mutex = new Object();
public ThreeThreadComunication(int[] array, AtomicInteger counter){
this.counter = counter;
this.array = array;
}
#Override
public void run() {
int i = 0;
while(i < array.length){
synchronized(mutex){
if(Integer.parseInt(Thread.currentThread().getName()) == counter.get()){
System.out.println(array[i]);
if(counter.get() == 3){
counter.getAndSet(1);
}else{
int c = counter.get();
counter.getAndSet(++c);
}
i++;
}
mutex.notifyAll();
try {
mutex.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
package com.sourav.mock.Thread;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreeThreadComunicationTest {
public static void main(String[] args) {
AtomicInteger counter = new AtomicInteger(1);
int[] array1 = new int[]{1, 4, 7};
int[] array2 = new int[]{2, 5, 8};
int[] array3 = new int[]{3, 6, 9};
ThreeThreadComunication obj1 = new ThreeThreadComunication(array1, counter);
ThreeThreadComunication obj2 = new ThreeThreadComunication(array2, counter);
ThreeThreadComunication obj3 = new ThreeThreadComunication(array3, counter);
Thread t1 = new Thread(obj1, "1");
Thread t2 = new Thread(obj2, "2");
Thread t3 = new Thread(obj3, "3");
t1.start();
t2.start();
t3.start();
}
}
public class EvenOdd1 {
//public static String str ="str1";
public static void main(String[] args) {
// TODO Auto-generated method stub
EvenOdd1 edd1 = new EvenOdd1();
AbThread tr2 = new AbThread(0,edd1);
AbThread tr3 = new AbThread(1,edd1);
AbThread tr4 = new AbThread(2,edd1);
tr2.start();
tr3.start();
tr4.start();
}
}
class AbThread extends Thread {
int mod;
int mod_count=1;
EvenOdd1 edd1;
public static int count=1;
int num_thread=3;
public AbThread(int mod,EvenOdd1 edd1){
this.mod = mod;
this.edd1 = edd1;
}
public void run()
{
synchronized(edd1)
{
try{
while(true){
while(count%num_thread!=mod)
edd1.wait();
if(count==30)
break;
print();
edd1.wait();
}
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void print()
{
int val = mod==1?2*mod_count:(mod==2?3*mod_count:4*mod_count);
System.out.println(Thread.currentThread().getName() + " : " + val);
edd1.notifyAll();
count=count+1;
this.mod_count++ ;
}
}
public class PrintThreadsSequentially {
static int number = 1;
static final int PRINT_NUMBERS_UPTO = 20;
static Object lock = new Object();
static class SequentialThread extends Thread {
int remainder = 0;
int noOfThreads = 0;
public SequentialThread(String name, int remainder, int noOfThreads) {
super(name);
this.remainder = remainder;
this.noOfThreads = noOfThreads;
}
#Override
public void run() {
while (number < PRINT_NUMBERS_UPTO) {
synchronized (lock) {
while (number % noOfThreads != remainder) { // wait for numbers other than remainder
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(getName() + " value " + number);
number++;
lock.notifyAll();
}
}
}
}
public static void main(String[] args) {
SequentialThread first = new SequentialThread("First Thread", 0, 4);
SequentialThread second = new SequentialThread("Second Thread", 1, 4);
SequentialThread third = new SequentialThread("Third Thread", 2, 4);
SequentialThread fourth = new SequentialThread("Fourth Thread", 3, 4);
first.start(); second.start(); third.start(); fourth.start();
}
}
The ThreadSynchronization class can be used to print numbers between 'n' no. of threads in sequence.
The logic is to create a common object between each of the consecutive threads and use 'wait', 'notify' to print the numbers in sequence.
Note: Last thread will share an object with the first thread.
You can change the 'maxThreads' value to increase or decrease the number of thread in the program before running it.
import java.util.ArrayList;
import java.util.List;
public class ThreadSynchronization {
public static int i = 1;
public static final int maxThreads = 10;
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
for (int i = 0; i < maxThreads; i++) {
list.add(new Object());
}
Object currObject = list.get(maxThreads - 1);
for (int i = 0; i < maxThreads; i++) {
Object nextObject = list.get(i);
RunnableClass1 a = new RunnableClass1(currObject, nextObject, i == 0 ? true : false);
Thread th = new Thread(a);
th.setName("Thread - " + (i + 1));
th.start();
currObject = list.get(i);
}
}
}
class RunnableClass implements Runnable {
private Object currObject;
private Object nextObject;
private boolean firstThread;
public RunnableClass(Object currObject, Object nextObject, boolean first) {
this.currObject = currObject;
this.nextObject = nextObject;
this.firstThread = first;
}
#Override
public void run() {
int i = 0;
try {
if (firstThread) {
Thread.sleep(5000);
firstThread = false;
System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++);
synchronized (nextObject) {
nextObject.notify();
}
}
while (i++ < Integer.MAX_VALUE) {
synchronized (currObject) {
currObject.wait();
}
System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++);
Thread.sleep(1000);
synchronized (nextObject) {
nextObject.notify();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
I have tried it below simple way to print in sequence using three threads and it is working well.
public class AppPrint123 {
static int count = 1;
static int counter = 1;
static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
public void run() {
while (true) {
synchronized (lock) {
try {
Thread.sleep(100);
while (count != 1) {
lock.wait();
}
System.out.println(Thread.currentThread().getName() + ": " + counter);
count++;
counter++;
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notifyAll();
}
}
}
}, "T1");
Thread t2 = new Thread(new Runnable() {
public void run() {
while (true) {
synchronized (lock) {
try {
Thread.sleep(100);
while (count != 2) {
lock.wait();
}
System.out.println(Thread.currentThread().getName() + ": " + counter);
counter++;
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notifyAll();
}
}
}
}, "T2");
Thread t3 = new Thread(new Runnable() {
public void run() {
while (true) {
synchronized (lock) {
try {
Thread.sleep(100);
while (count != 3) {
lock.wait();
}
System.out.println(Thread.currentThread().getName() + ": " + counter);
count = count - 2;
counter++;
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notifyAll();
}
}
}
}, "T3");
t1.start();
t2.start();
t3.start();
}
}
You can print count variable instead if you want to generate output like 123123123 in sequence using three threads.
Bad way to do but ask is to implement using multiple threads:
private static AtomicInteger currentThreadNo = new AtomicInteger(0);
private static int currentNo = 1;
private static final Object lock = new Object();
Above, these values are static so that they remain same for all the worker objects.
import java.util.concurrent.atomic.AtomicInteger;
public class PrintNumbersUsingNThreads implements Runnable {
private final int threadNo;
private final int totalThreads;
private static AtomicInteger currentThreadNo = new AtomicInteger(0);
private static int currentNo = 1;
private static final Object lock = new Object();
public PrintNumbersUsingNThreads(int threadNo, int totalThreads) {
this.threadNo = threadNo;
this.totalThreads = totalThreads;
}
#Override
public void run() {
while (true) {
while (currentThreadNo.get() % totalThreads != threadNo) {
try {
synchronized (lock) {
lock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " printing " + currentNo);
currentNo++;
int curr = currentThreadNo.get();
if (curr == totalThreads) {
currentThreadNo.set(1);
} else {
currentThreadNo.incrementAndGet();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock) {
lock.notifyAll();
}
}
}
public static void main(String[] args) {
int totalThreads = 3;
for(int i = 0; i < totalThreads; i++){
new Thread(new PrintNumbersUsingNThreads(i,totalThreads),"thread"+i).start();
}
}
}
output:
thread0 printing 1
thread1 printing 2
thread2 printing 3
thread0 printing 4
thread1 printing 5
thread2 printing 6
thread0 printing 7
thread1 printing 8
thread2 printing 9
thread0 printing 10
thread1 printing 11
thread2 printing 12
thread0 printing 13
thread1 printing 14
thread2 printing 15
thread0 printing 16
thread1 printing 17
thread2 printing 18
Below is very generic code. i agree it is not good practice to use multiple threads for such cases
class MultipleThreads implements Runnable {
AtomicInteger integer;
int max_val = 100;
int remainder;
int numofThreads;
public MultipleThreads(AtomicInteger integer, int remainder, int numofThreads) {
this.integer = integer;
this.remainder = remainder;
this.numofThreads = numofThreads;
}
#Override
public void run() {
while (integer.intValue() <= max_val) {
synchronized (integer) {
while (integer.intValue() % numofThreads != remainder) {
try {
integer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (integer.intValue() > max_val)
break;
System.out.println("printing :" + Thread.currentThread().getName() + " : " + integer.getAndIncrement());
integer.notifyAll();
}
}
}
}
public class ThreadSynchronization {
public static void main(String[] args) {
AtomicInteger at = new AtomicInteger(1);
MultipleThreads th1 = new MultipleThreads(at, 1, 5);
MultipleThreads th2 = new MultipleThreads(at, 2, 5);
MultipleThreads th3 = new MultipleThreads(at, 3, 5);
MultipleThreads th4 = new MultipleThreads(at, 4, 5);
MultipleThreads th5 = new MultipleThreads(at, 0, 5);
new Thread(th1).start();
new Thread(th2).start();
new Thread(th3).start();
new Thread(th4).start();
new Thread(th5).start();
}
}
Also, make sure to use pthread_cond_broadcast instead of phread_cond_signal
#include "stdio.h"
#include "stdlib.h"
#include "pthread.h"
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER;
void *functionCount1();
void *functionCount2();
void *functionCount3();
int count = 0;
#define COUNT_DONE 10
void main()
{
pthread_t thread1, thread2, thread3;
pthread_create( &thread1, NULL, &functionCount1, NULL);
pthread_create( &thread2, NULL, &functionCount2, NULL);
pthread_create( &thread3, NULL, &functionCount3, NULL);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
pthread_join( thread3, NULL);
exit(0);
}
// Let me write what I think
// we can;t do he %2 %3 since multiple threads may satisfy the conditions.
// count = 0; count % 3 = 0
// count = 1; count % 3 = 1
// count = 2; count % 3 = 2
// count = 3; cooun % 3 = 0
// Print odd numbers
void *functionCount1()
{
for(;;) {
// Lock mutex and then wait for signal to relase mutex
pthread_mutex_lock( &count_mutex );
if ( count % 3 == 0 ) {
printf("Counter value functionCount1: %d\n",count);
count++;
pthread_cond_broadcast( &condition_var );
} else {
pthread_cond_wait( &condition_var, &count_mutex );
}
if ( count >= COUNT_DONE ) {
pthread_mutex_unlock( &count_mutex );
return(NULL);
}
pthread_mutex_unlock( &count_mutex );
}
}
// print even numbers
void *functionCount2()
{
for(;;) {
// Lock mutex and then wait for signal to relase mutex
pthread_mutex_lock( &count_mutex );
if ( count % 3 == 1 ) {
printf("Counter value functionCount2: %d\n",count);
count++;
pthread_cond_broadcast( &condition_var );
} else {
pthread_cond_wait( &condition_var, &count_mutex );
}
if( count >= COUNT_DONE ) {
pthread_mutex_unlock( &count_mutex );
return(NULL);
}
pthread_mutex_unlock( &count_mutex );
}
}
// print even numbers
void *functionCount3()
{
for(;;) {
// Lock mutex and then wait for signal to relase mutex
pthread_mutex_lock( &count_mutex );
if ( count % 3 == 2 ) {
printf("Counter value functionCount3: %d\n",count);
count++;
pthread_cond_broadcast( &condition_var );
} else {
pthread_cond_wait( &condition_var, &count_mutex );
}
if( count >= COUNT_DONE ) {
pthread_mutex_unlock( &count_mutex );
return(NULL);
}
pthread_mutex_unlock( &count_mutex );
}
}
Here is my solution. It is pretty simple and easy to understand. It will help if you are using static variables...
Note that using a lock object is crucial as I tried initially with the this keyword(ex: synchronized(this) ), but it was not been synchronized among all threads.
public class Assignment_Three_Threads {
public static int TotalNumberOfThreads = 3;
public static void main(String[] args) {
multiThread t1 = new multiThread(1);
multiThread t2 = new multiThread(2);
multiThread t3 = new multiThread(3);
t1.start();
t2.start();
t3.start();
}
}
class multiThread extends Thread{
int k=2;
private int threadId ;
private static int threadIdToRun = 1;
private static final Object lock = new Object();
multiThread(int id)
{
super();
this.threadId = id;
}
#Override
public void run() {
for (int i = 0; i < k; i++) {
synchronized (lock) {
while(true) {
if (this.threadId != threadIdToRun) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
if (this.threadId == threadIdToRun) {
System.out.println("Thread : " + this.threadId);
threadIdToRun =
(threadIdToRun % Assignment_Three_Threads.TotalNumberOfThreads) + 1;
// System.out.println("Next Thread to be printed " + threadIdToRun);
lock.notifyAll();
break;
}
}
}
}
}
}
A general solution for any number of Threads-
for 3 thread logic =MIN % 3 != reminder
for 4 thread= MIN % 4 != reminder
public class PrintSequenceRunnable1 implements Runnable {
int reminder;
static Object lock=new Object();
static int MIN=1;
int MAX=20;
PrintSequenceRunnable1(int reminder){
this.reminder=reminder;
}
public static void main(String[] args) {
Thread t1= new Thread(new PrintSequenceRunnable1(1),"T1");
Thread t2= new Thread(new PrintSequenceRunnable1(2),"T2");
Thread t3= new Thread(new PrintSequenceRunnable1(0),"T3");
t1.start();
t2.start();
t3.start();
}
#Override
public void run() {
synchronized (lock) {
while (MIN < MAX - 1) {
while (MIN % 3 != reminder) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "-" + MIN);
MIN++;
lock.notifyAll();
}
}
}
}
public class ThreadTask implements Runnable {
private int counter;
private int threadID;
private final Object lock;
private int prev;
public ThreadTask(Object obj, int threadid, int counter){
this.lock = obj; // monitor
this.threadID = threadid; //id of thread
this.counter = counter;
this.prev =threadid + 1;
}
public void run(){
while(counter<100){
synchronized(lock){
if(counter == this.prev && this.threadID % 3 == this.threadID){
System.out.println("T" + this.threadID + " = " + this.prev);
this.prev = this.prev + 3;
}
counter++;
lock.notifyAll();
try{
lock.wait();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
public class ThreadMain {
static volatile int counter = 1;
public static void main(String args[]) throws InterruptedException{
final Object lock = new Object();
ThreadTask first = new ThreadTask(lock, 0, counter);
ThreadTask second = new ThreadTask(lock, 1, counter);
ThreadTask third = new ThreadTask(lock, 2, counter);
Thread t1 = new Thread(first, "first");
Thread t2 = new Thread(second, "second");
Thread t3 = new Thread(third, "third");
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
}
}
package ThreadCoreConcepts;
import java.util.ArrayList;
import java.util.List;
/**
* 3 Thread T1,T2,T3 will print output {1,2,3 4,5,6 7,8,9} Where T1 will print
* {1,4,7} , T2 will print { 2,5,8} and T3 will print {3,6,9}
*
* #author harsmahe
*
*/
public class ThreeThreadSequenceGen {
private volatile static int value = 1;
public static void main(String args[]) throws InterruptedException {
ThreeThreadSequenceGen gen = new ThreeThreadSequenceGen();
Object mutex = new Object();
Thread t1 = new Thread(gen.new RunThread(1, mutex));
t1.setName("1");
Thread t2 = new Thread(gen.new RunThread(2, mutex));
t2.setName("2");
Thread t3 = new Thread(gen.new RunThread(3, mutex));
t3.setName("3");
t1.start();
t2.start();
t3.start();
}
class RunThread implements Runnable {
private int start = 0;
private Object mutex;
private List<Integer> list = new ArrayList<Integer>();
public RunThread(final int start, Object mutex) {
// TODO Auto-generated constructor stub
this.start = start;
this.mutex = mutex;
}
#Override
public void run() {
try {
while (value <= 9) {
// while (true) {
// TODO Auto-generated method stub
int name = Integer.valueOf(Thread.currentThread().getName());
// System.out.println("[" + Thread.currentThread().getName()
// + "]");
// notifyAll();
synchronized (mutex) {
if (name == 1 && value == start) {
list.add(value);
System.out.println("[" + Thread.currentThread().getName() + "]" + value);
start = start + 3;
value++;
mutex.notifyAll();
mutex.wait();
} else if (name == 2 && value == start) {
System.out.println("[" + Thread.currentThread().getName() + "]" + value);
list.add(value);
start = start + 3;
value++;
mutex.notifyAll();
mutex.wait();
} else if (name == 3 && value == start) {
System.out.println("[" + Thread.currentThread().getName() + "]" + value);
list.add(value);
start = start + 3;
value++;
mutex.notifyAll();
if (value < 9) {
mutex.wait();
}
} else {
mutex.notifyAll();
// mutex.wait();
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// System.out.println(list);
}
}
}
}

Sequence number using thread Synchronization

I want to print a series of 1 to 100 number using n number of threads (lets take 10 threads for this). Condition is 1st thread will have a sequence number from 1, 11,21....91, 2nd thread will have a sequence 2,12,22.....92 and so on. All other threads will have a sequence number like that. Now I want to print number in sequence 1 to 100. I know we can use synchronization, wait and notify method and using a variable or flag counter but I don't think this is a good idea to use it. I want to use without concurrency (like executors etc) how will I do that. Please suggest.
public class PrintNumberSequenceUsingRunnable {
int notifyValue = 1;
public static void main(String[] args) {
PrintNumberSequenceUsingRunnable sequence = new PrintNumberSequenceUsingRunnable();
Thread f = new Thread(new First(sequence), "Fisrt");
Thread s = new Thread(new Second(sequence), "Second");
Thread t = new Thread(new Third(sequence), "Third");
f.start();
s.start();
t.start();
}
}
class First implements Runnable {
PrintNumberSequenceUsingRunnable sequence;
public First(PrintNumberSequenceUsingRunnable sequence) {
this.sequence = sequence;
}
#Override
public void run() {
printFist();
}
private void printFist() {
synchronized (sequence) {
for (int i = 1; i <= 20; i += 3) {
while (sequence.notifyValue != 1) {
try {
sequence.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " + i);
sequence.notifyValue = 2;
sequence.notifyAll();
}
}
}
}
class Second implements Runnable {
PrintNumberSequenceUsingRunnable sequence;
public Second(PrintNumberSequenceUsingRunnable sequence) {
this.sequence = sequence;
}
#Override
public void run() {
printSecond();
}
private void printSecond() {
synchronized (sequence) {
for (int i = 2; i <= 20; i += 3) {
while (sequence.notifyValue != 2) {
try {
sequence.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " + i);
sequence.notifyValue = 3;
sequence.notifyAll();
}
}
}
}
class Third implements Runnable {
PrintNumberSequenceUsingRunnable sequence;
public Third(PrintNumberSequenceUsingRunnable sequence) {
this.sequence = sequence;
}
#Override
public void run() {
printThrid();
}
private void printThrid() {
synchronized (sequence) {
for (int i = 3; i <= 20; i += 3) {
while (sequence.notifyValue != 3) {
try {
sequence.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " + i);
sequence.notifyValue = 1;
sequence.notifyAll();
}
}
}
}
You need to have values sorted on each threads. Each time a thread writes a number, it triggers an event in an event bus. All threads are subscribed to the event.
You start the system by triggering the event [minimum value - 1].
Each thread will receive a notification that the value [minimum value - 1] has been published. Only the thread that has the value [minimum value] will act and will trigger a new event for value [minimum value + 1].
Edit: I haven't tested it, but something like this.
static void main(String[] args) {
List<Deque<Integer>> publishQueues = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
new Thread(new Worker(i, publishQueues)).start();
}
}
class Worker implements Runnable {
Deque subscriberQueue;
List<Deque<Integer>> publishQueues;
int i;
Worker(int i, List<Deque<Integer>> publishQueues) {
this.i = i;
this.publishQueues = publishQueues;
this.subscriberQueue = new ConcurrentLinkedDeque<>();
this.publishQueues.add(this.subscriberQueue);
}
void Run() {
LinkedList<Integer> ints = new LinkedList<>();
for (int j = i; j <= 100; j+=10) {
ints.add(j);
}
while (true) {
Integer publishedInteger = subscriberQueue.poll();
if (publishedInteger == ints.getFirst() - 1) {
Integer integer = ints.poll();
System.out.println(integer);
for (Dequeu<Integer> publishQueue : publishQueues) {
publishQueue.addLast(integer);
}
}
}
}
}

Categories