I need to write a program, which has an integer array. Lets say the array's length is 3. To start with, it is empty. Now, the program has to use two threads, one writes integers into the empty array, the other one deletes them out of it. I will give you an example:
thread1 put in value 1 //array has value: 1
thread1 put in value 2 //array has two values: 1 and 2
thread2 deleted value 2 //array now has only one value: 1
thread1 put in value 3 //array has two values: 1 and 3
thread1 put in value 4 //array has three values: 1,3,4
thread1 wants to put value 5 into the array, but it has to wait, because the array is full
thread2 deleted value 4// array has 2 values: 1, 3 and so on........
My teacher said, it would be best and easiest to do all of this by implementing for cycles with a specified counter(for example each thread has to go through 10 cycles). Now i have written some code, but i just cant figure out how to implement the synchronized object(the integer array) so that both threads can use it. Heres the code:
public class Antras {
public static void main(String[] args) {
System.out.println("Program starts working");
begin();
System.out.println("Program ends work");
}
public static void begin() {
synchronizationObject channel = new synchronizationObject();
try {
Thread putIn = new ReadThread(channel);
putIn.start();
Thread takeOut = new WriteThread(channel);
takeOut.start();
putIn.join();
takeOut.join();
System.out.println("main() ended work");
} catch (InterruptedException exc) {
System.out.println("Error " + exc);
}
}
}
class ReadThread extends Thread {
private synchronizationObject channel;
public ReadThread(synchronizationObject channel) {
this.channel = channel;
}
public void run() {
System.out.println("Thread " + this + "working");
channel.working = false;
System.out.println("Thread " + this + "ends work");
}
}
class WriteThread extends Thread {
private synchronizationObject channel;
public WriteThread(synchronizationObject channel) {
this.channel = channel;
}
public void run() {
System.out.println("Thread " + this + "working");
System.out.println("Thread " + this + "end work");
}
}
class synchronizationObject {
public static int N = 3;
int[] arrayOfInts = new int[N];
synchronized void takeOut() {
}
synchronized void putIn(int d) {
}
}
synchronized int putIn(int d) {
if(full == N){
try {
wait();
System.out.println("Array full, thread waits");
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
buffer[idxdeti] = d;
System.out.println("Value " + d + " added");
idxdeti++;
full++;
if (idxdeti == N){
idxdeti = 0;
}
}
return d; //returns the value
}
This is the WriteThread's run method:
public void run() {
System.out.println("WriteThread" + this + "started");
for(int i = 0; i<10; i++){
channel.putIn(i); //puts in a value
}
System.out.println("WriteThread" + this + "ended");
}
Now I just don't know how to return a value to the takeOut method, so when it works, it removes the given value.
Related
my exercise is composed of an SharedResource with an array, a NumberGenerator Class and a SumClass.
2 Threads of NumberGenerator and 2 Threads of SumClass.
I have to insert numbers in the array from the SharedResource with both threads of NumberGenerator Class.
This part is done correctly.
My problem is in the run method of the NumberGenerator Class.
These Threads must read alternatively the index of the array, the first thread, lets call it H1, read the index 0-2-4-6... even index, the another one, H2, odd index... But when 1 thread is running the other must wait.
So the output should be something like this:
Array:[10,35,24,18]
Thread name: H1 - Number:10
Thread name: H2 - Number:35
Thread name: H1 - Number:24
Thread name: H2 - Number:18
My problem resides in the notify and wait methods. When I call the wait method, it automatically stop both Threads even when a notifyAll is present.
I need to just use 1 method, I cant use a evenPrint method and an OddPrint method for example.
Code of my class:
public class SumatoriaThread extends Thread{
String name;
NumerosCompartidos compartidos; // Object that contains the array.
double sumatoria; //Parameter used to sum all the numbers
static int pos = 0; // pos of the object
static int threadOrder = 0; //just a way to set the order of the Threads.
int priority; //Value of the priority
public SumatoriaThread(NumerosCompartidos compartidos, String name){
this.name = name;
this.compartidos = compartidos;
sumatoria = 0;
priority = threadOrder;
threadOrder++;
System.out.println("Hilo " + this.name + " creado.");
}
public void run() {
//Array Length
int length = this.compartidos.length();
int i = 0;
while (pos < length) {
//Don't actually know if this is correct.
synchronized (this) {
//Just to be sure that the first Thread run before the second one.
if (priority == 1) {
try {
priority = 0;
//Call a wait method until the next notify runs.
this.wait();
} catch (InterruptedException ex) {
Logger.getLogger(SumatoriaThread.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
//Even numbers
if (pos % 2 == 0) {
System.out.println("Nombre Thead: " + Thread.currentThread().getName() + " valor numero: " + this.compartidos.getValor(pos));
pos++;
//To activate the Thread which is waiting.
this.notifyAll();
try {
//Then I set to wait this one.
this.wait();
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
System.out.println("Nombre Thead: " + Thread.currentThread().getName() + " valor numero: " + this.compartidos.getValor(pos + 1));
pos++;
this.notifyAll();
try {
this.wait();
} catch (InterruptedException ex) {
Logger.getLogger(SumatoriaThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
}
}
I want fibonacci series to be printed by threads and the 1st number of the series should be printed by 1st thread then 2nd number by 2nd thread then 3rd by 1st thread and 4th by 2nd and so on.
I tried this code by using arrays like printing the array elements using thread but I am not able to switch between the threads.
class Fibonacci{
void printFibonacci() {
int fibArray[] = new int[10];
int a = 0;
int b = 1;
fibArray[0] = a;
fibArray[1] = b;
int c;
for(int i=2;i<10;i++) {
c = a+b;
fibArray[i] = c;
a = b;
b = c;
}
for(int i=0;i<10;i++) {
if(Integer.parseInt(Thread.currentThread().getName())%2==0 && (i%2==0))
{
System.out.println("Thread " +Thread.currentThread().getName()+" "+fibArray[i]);
try{
wait();
}catch(Exception e) {}
}
else if(Integer.parseInt(Thread.currentThread().getName())%2!=0 && (i%2!=0))
{
System.out.println("Thread " +Thread.currentThread().getName()+" "+fibArray[i]);
}
}
}
}
public class FibonacciUsingThread {
public static void main(String[] args) throws Exception {
Fibonacci f = new Fibonacci();
Thread t1 = new Thread(()->
{
f.printFibonacci();
});
Thread t2 = new Thread(()->
{
f.printFibonacci();
});
t1.setName("0");
t2.setName("1");
t1.start();
t1.join();
t2.start();
}
}
The following line in your code is causing t1 to finish before t2 can start.
t1.join();
Apart from this, you need to synchronize on the method, printFibonacci.
You can do it as follows:
class Fibonacci {
synchronized void printFibonacci() throws InterruptedException {
int fibArray[] = new int[10];
int a = 0;
int b = 1;
fibArray[0] = a;
fibArray[1] = b;
int c;
for (int i = 2; i < 10; i++) {
c = a + b;
fibArray[i] = c;
a = b;
b = c;
}
for (int i = 0; i < 10; i++) {
String currentThreadName = Thread.currentThread().getName();
if (currentThreadName.equals("1")) {
if (i % 2 == 0) {
System.out.println("Thread " + Thread.currentThread().getName() + " " + fibArray[i]);
notify();
} else {
wait();
}
} else if (currentThreadName.equals("0")) {
if (i % 2 == 1) {
System.out.println("Thread " + Thread.currentThread().getName() + " " + fibArray[i]);
notify();
} else {
wait();
}
}
}
}
}
public class Main {
public static void main(String[] args) {
Fibonacci f = new Fibonacci();
Thread t1 = new Thread(() -> {
try {
f.printFibonacci();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
f.printFibonacci();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.setName("0");
t2.setName("1");
t1.start();
t2.start();
}
}
Output:
Thread 1 0
Thread 0 1
Thread 1 1
Thread 0 2
Thread 1 3
Thread 0 5
Thread 1 8
Thread 0 13
Thread 1 21
Thread 0 34
Apart from all being said and already answered, I would just like to add one alternative approach to Fibonacci sequence implemetation, without arrays and in-advance dimensioning:
public class Fibonacci {
private int index = -1;
private int previous = 0;
private int last = 1;
synchronized public int getNext() {
index++;
if( index == 0 ) return previous;
if( index == 1 ) return last;
int next = last + previous;
if( next < 0 ) throw new ArithmeticException( "integer overflow" );
previous = last;
last = next;
return next;
}
}
Limited only by overflow of numeric data type, in this case integer.
As "#Live and Let Live" pointed out, correctness-wise the main issues with your code is the missing synchronized clause and calling join of the first thread before starting the second thread.
IMO you could clean the code a bit by first separating a bite the concerns, namely, the class Fibonacci would only responsible for calculation the Fibonacci of a given array:
class Fibonacci{
void getFibonacci(int[] fibArray) {
int a = 0;
int b = 1;
fibArray[0] = a;
fibArray[1] = b;
int c;
for(int i=2;i<fibArray.length;i++) {
c = a+b;
fibArray[i] = c;
a = b;
b = c;
}
}
}
In this way, you keep your Fibonacci class concise without any thread-related code. Moreover, the getFibonacci is now more abstract; you can calculate the fib of more than just 10 elements like you had before.
Then on the class FibonacciUsingThread:
public class FibonacciUsingThread {
public static void main(String[] args) throws Exception {
int [] array_fib = new int[10];
Fibonacci f = new Fibonacci();
f.getFibonacci(array_fib);
Thread t1 = new Thread(()->
{
for(int i = 0; i < array_fib.length; i+=2)
System.out.println("Thread 1:" + array_fib[i]);
});
Thread t2 = new Thread(()->
{
for(int i = 1; i < array_fib.length; i+=2)
System.out.println("Thread 2:" + array_fib[i]);
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
First, you calculate the Fibonaccis using the main thread, there is no point in having all the threads calculate the same thing. Afterward, you specified that Thread 1 and Thread 2 will print the even and odd positions, respectively.
Unless this is just an exercise to play around with threads and synchronization there is not much sense in using threads to do this kind of work. In your code, the part worth parallelizing is the calculation of the Fibonacci numbers themselves, not the printing part.
The code previously shown will not print the Fibonacci numbers in order, for that you need to ensure that the threads wait for one another after iterating through each element of the array. Hence, you need to adapt the code that will be executed by the threads, namely:
Thread t1 = new Thread(()->
{
synchronized (array_fib){
for(int i = 0; i < array_fib.length; i++)
if(i % 2 == 0) {
System.out.println("Thread 1:" + array_fib[i]);
try {
array_fib.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
array_fib.notify();
}
});
Thread t2 = new Thread(()->
{
synchronized (array_fib){
for(int i = 0; i < array_fib.length; i++)
if(i % 2 != 0) {
System.out.println("Thread 2:" + array_fib[i]);
try {
array_fib.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
array_fib.notify();
}
});
We can remove the code redundancy by extracting a method with the work that will be assigned to the Threads. For instance:
private static void printFib(String threadName, int[] array_fib, Predicate<Integer> predicate) {
for (int i = 0; i < array_fib.length; i++)
if (predicate.test(i)) {
System.out.println(threadName + " : " + array_fib[i]);
try {
array_fib.wait();
} catch (InterruptedException e) {
// do something about it
}
} else
array_fib.notify();
}
and the main code:
public static void main(String[] args) throws Exception{
int [] array_fib = new int[10];
Fibonacci f = new Fibonacci();
f.getFibonacci(array_fib);
Thread t1 = new Thread(()-> {
synchronized (array_fib){
printFib("Thread 1:", array_fib, i1 -> i1 % 2 == 0);
}
});
Thread t2 = new Thread(()-> {
synchronized (array_fib){
printFib("Thread 2:", array_fib, i1 -> i1 % 2 != 0);
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
As an alternative, you can use a fair Semaphore to alternate between threads, and an AtomicReference to keep the shared status. Here's an example:
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicReference;
public class FibonacciConcurrent {
public static void main(String[] args) throws InterruptedException {
// needs to be fair to alternate between threads
Semaphore semaphore = new Semaphore(1, true);
// set previous to 1 so that 2nd fibonacci number is correctly calculated to be 0+1=1
Status initialStatus = new Status(1, 0, 1);
AtomicReference<Status> statusRef = new AtomicReference<>(initialStatus);
Fibonacci fibonacci = new Fibonacci(20, semaphore, statusRef);
Thread thread1 = new Thread(fibonacci);
Thread thread2 = new Thread(fibonacci);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
}
private static final class Status {
private final long previous;
private final long current;
private final int currentIndex;
private Status(long previous, long current, int currentIndex) {
this.previous = previous;
this.current = current;
this.currentIndex = currentIndex;
}
}
private static final class Fibonacci implements Runnable {
private final int target;
private final Semaphore semaphore;
private final AtomicReference<Status> statusRef;
private Fibonacci(int target, Semaphore semaphore, AtomicReference<Status> statusRef) {
this.target = target;
this.semaphore = semaphore;
this.statusRef = statusRef;
}
#Override
public void run() {
try {
process();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted", e);
}
}
private void process() throws InterruptedException {
while (!Thread.currentThread().isInterrupted()) {
try {
semaphore.acquire();
Status status = statusRef.get();
String threadName = Thread.currentThread().getName();
if (status.currentIndex > target) return;
System.out.println(
threadName + ": fibonacci number #" + status.currentIndex + " - " + status.current);
long next = status.previous + status.current;
Status newStatus = new Status(status.current, next, status.currentIndex + 1);
statusRef.set(newStatus);
} finally {
semaphore.release();
}
}
}
}
}
Will print:
Thread-0: fibonacci number #1 - 0
Thread-1: fibonacci number #2 - 1
Thread-0: fibonacci number #3 - 1
Thread-1: fibonacci number #4 - 2
Thread-0: fibonacci number #5 - 3
Note that this solution does not only print on the threads - it does the actual calculation on the threads as well - e.g. when it's Thread A's turn, it uses the previous status that was calculated by Thread B to calculate the next fibonacci number.
I have tried this code. But after printing 0 , it doesn't print anything.
It is blocking due to some lock I think.
public class EvenOdd implements Runnable {
private Object o = new Object();
private volatile int i = 0;
public void run() {
try {
System.out.println();
if ( Thread.currentThread().getName().equals( "Even")) {
printEven();
} else {
printOdd();
}
} catch ( Exception ee) {
ee.printStackTrace();
}
}
private void printEven() throws InterruptedException {
while ( true) {
synchronized ( o) {
while ( this.i % 2 == 0) {
o.wait();
}
System.out.println( Thread.currentThread().getName() + i);
i++;
o.notify();
}
}
}
private void printOdd() throws InterruptedException {
while ( true) {
synchronized ( o) {
while ( this.i % 2 != 0) {
o.wait();
}
System.out.println( Thread.currentThread().getName() + i);
i++;
o.notify();
}
}
}
}
My TestClass:
EvenOdd x = new EvenOdd();
new Thread(x,"Even").start();
new Thread(x,"Odd").start();
Where am I wrong?
Thank.
P.S : I know this type of question has been asked many times , but I want to try by my own.
My guesses is you are;
using one Runnable but both of then think they are even i.e. they both see the first value of 0
printEven has to wait for an odd number ad printOdd has to wait for an even number
EDIT: After running the code the OP fixed the code, it prints
0
1
as expected. It may sometimes print 0 and 0 randomly as the first check for odd/even is not synchronized.
It's a simple deadlock:
Thread 1 waits for someone to notify on the lock. Thread 2 waits for someone to notify on the same lock.
Since no one ever gets to o.notify();, nothing happens.
And i is 0 when both threads start, so both first call printEven(). Now when that has happened, both threads will then call printOdd() in the next round.
The basic concept is when one thread is running, the other has to wait. Once the thread prints the value, it has to wait until the other thread prints. This is achieved by using wait/notify mechanism.
When Odd thread completes printing the value, it notifies the waiting thread(Even thread) and the Even thread becomes ready to run but will wait for the lock to be released by the Odd thread. Now the odd thread calls wait on the locker object so that it releases the lock and goes to wait state. At this point, the only thread waiting for locker object's lock is Even thread and it runs. This process continues alternatively.
public class Test {
public static void main(String[] args) {
Object locker = new Object();
Thread t1 = new Thread(new OddWorker(locker));
Thread t2 = new Thread(new EvenWorker(locker));
t1.start();
t2.start();
}
}
class OddWorker implements Runnable {
private Object locker;
private int number = 1, count = 1;
OddWorker(Object locker) {
this.locker = locker;
}
#Override
public void run() {
synchronized (locker){
do {
try {
System.out.println(Thread.currentThread().getName() + ": " + number);
number += 2;
locker.notify();
locker.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while(++count < 11);
locker.notify();
}
}
}
class EvenWorker implements Runnable {
private Object locker;
private int number = 2, count = 1;
EvenWorker(Object locker) {
this.locker = locker;
}
#Override
public void run() {
synchronized (locker){
do {
try {
System.out.println(Thread.currentThread().getName() + ": " + number);
number += 2;
locker.notify();
locker.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while(++count < 11);
}
}
}
How to create a cyclic exchange of three threads? That is: first thread must send data to second, second to third and third thread must send data to first.
I wrote some code, but threads exchange in random oder.
class DataClass {
int value;
String message;
DataClass(int v, String s) {
value = v;
message = s;
}
int getValue() {
return (value);
}
String getMassage() {
return (message);
}
}
class Loop implements Runnable {
int counter;
String name;
Exchanger<DataClass> exchanger;
Loop(int startValue, String id, Exchanger<DataClass> ex) {
counter = startValue;
name = id;
exchanger = ex;
System.out.println(name + ": created");
}
public void run() {
System.out.println(name + ": started");
DataClass data = new DataClass(counter, name);
for (int i = 0; i < 3; ++i) {
try {
DataClass newData = exchanger.exchange(data);
counter += newData.getValue();
System.out.println(name + ": from "
+ newData.getMassage() + ": data: "
+ newData.getValue() + ": state = " + counter);
} catch (InterruptedException e) {
System.err.println(e.toString());
}
}
System.out.println(name + ": ended");
}
}
public class ExchangerDemo {
public static void main(String args[]) {
System.out.println("Main process started");
Exchanger<DataClass> exchanger = new Exchanger<DataClass>();
Loop loop1 = new Loop(1, "First", exchanger);
Loop loop2 = new Loop(2, "Second", exchanger);
Loop loop3 = new Loop(3, "Third", exchanger);
new Thread(loop1).start();
new Thread(loop2).start();
new Thread(loop3).start();
System.out.println("Main process ended");
}
}
For your dependency you should make three classes, and have three distinct Exchange objects (one in each). So thread1 would be between 1 and 2 (output of 1 to 2), thread 2's would be between 2 and 3 and thread 3's exhanger would be between itself and 1. Remember the exchanger's would guard only until it had its input from its feeder, to till it passes to its receiver.
Also synchronized is not as bad as the books make out. use it. Watch http://www.youtube.com/watch?v=WTVooKLLVT8
Also for reference Best way of running two threads alternatively?
Also why do you need three threads? Can you use a thread pool and have each task to the 3 things ?
Basically what it does is that it prints the following numbers multiple of 2 and 3 in sequence like this
2 3 4 6 6 9 8 12 10 = this is the output
(2*1=2) (3*1=3) (2*2=4) (3*2=6) (2*3=6) (3*3=9) (2*4=8) (3*4=12) (2*5=10) = just a guide
here's my code so far, I'm having trouble displaying it in sequence. I've tried using wait and notify but it's a mess. So far this one is working.
public class Main {
public static void main(String[] args) throws InterruptedException {
final Thread mulof2 = new Thread(){
public void run() {
for (int i = 1; i <= 10; i++) {
int n = 2;
int result = n * i;
System.out.print(result + " ");
}
}
};
Thread mulof3 = new Thread(){
public void run() {
for (int i = 1; i <= 10; i++) {
int n = 3;
int result = n * i;
System.out.print(result + " ");
}
}
};
mulof2.start();
mulof3.start();
}
}
With Java 7 your first choice should be a Phaser. You'll only need one instance of it, created with new Phaser(1). You'll need just two methods for coordination: arrive and awaitAdvance.
Multiplication Table in java using Threads Concept
public class Multiplication extends Thread {
public void run() {
for (int i = 1; i < 10; i++) {
int n = 2;
int result = n * i;
System.out.print(i+"*"+n+"="+result+"\n");
}
}
public static void main(String[] args) throws InterruptedException {
Multiplication mul=new Multiplication();
mul.start();
}
}
Instead of printing during computation, you can aggregate the results into strings and then print both strings in order. After joining with the threads of course.
wait() and notify() are generally too low level, and too complex to use. Try using a more high-level abstraction like Semaphore.
You could have a pair of Semaphore instances: one which allows printing the next multiple of 2, and another one which allows printing the next multiple of 3. Once the next multiple of 2 has been printed, the thread should give a permit to print the next multiple of 3, and vice-versa.
Of course, the initial numbers of permits of the semaphores must be 1 for the multiple-of-2 semaphore, and 0 for the other one.
A simple modification would help you get the required sequence.
You need to declare a semaphore as other have pointed out private Semaphore semaphore;. Then declare another variable to denote which thread has to execute next such as private int threadToExecute; .
Next step is within your thread execute the code between semaphore.acquire(); and semaphore.release();
thread2:
try{
semaphore.acquire();
if(threadToExecute ==2)
semaphore.release();
//write your multiply by 2 code here
threadToExecute = 3;
semaphore.release();
}catch(Exception e){
//exceptions
}
This will nicely synchronize your output.
Below is the code that will give you desired results.
public class Main {
public static void main(String[] args) throws InterruptedException {
final Object lock1 = new Object();
final Object lock2 = new Object();
final Thread mulof2 = new Thread(){
public void run() {
for (int i = 1; i <= 10; i++) {
synchronized (lock1) {
synchronized (lock2) {
lock2.notify();
int n = 2;
int result = n * i;
printResult(result);
}
try {
lock1.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
Thread mulof3 = new Thread(){
public void run() {
for (int i = 1; i <= 10; i++) {
synchronized (lock2) {
synchronized (lock1) {
lock1.notify();
int n = 3;
int result = n * i;
printResult(result);
}
try {
lock2.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
mulof2.start();
mulof3.start();
}
static void printResult(int result)
{
try {
// Sleep a random length of time from 1-2s
System.out.print(result + " ");
Thread.sleep(new Random().nextInt(1000) + 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}