Ok, so I want to generate a random number for printing in a thread. One and two work fine, but three just prints out the same random number. So if a generates 1928, it sleeps for 1928 over and over again. How do I make dynamically random numbers? Three is the only one where I want to interrupt if another random number(num) is smaller than 1000.
package thread;
import java.util.Random;
public class Threads {
public static Thread one;
public static Thread two;
public static Thread three;
public static int numbers[] = { 1, 2, 3, 4, 5 };
public static String letters[] = { "a", "b", "c", "d", "e" };
public static float negatives[] = { -1, -2, -3, -4, -5 };
public static Random rand = new Random();
public static void main(String args[]) {
startSequences();
one.setName("one");
two.setName("two");
three.setName("three");
one.start();
two.start();
three.start();
}
public static void startSequences() {
one = new Thread() {
public void run() {
try {
System.out
.println("Numbers\n-----------------------------------");
for (int i = 0; i < numbers.length; i++) {
int a = rand.nextInt(3999);
System.out.printf(
"%s is sleeping for %d milliseconds. \n",
Thread.currentThread().getName(), a);
Thread.sleep(a);
System.out.println(Thread.currentThread().getName()
+ " is done sleeping.");
System.out.printf("current number is %s\n", numbers[i]);
}
} catch (InterruptedException e) {
System.out.printf("%s has been interrupted. How rude!",
Thread.currentThread().getName());
} finally {
System.out.printf("%s is finally done!\n", Thread
.currentThread().getName());
}
}
};
two = new Thread() {
public void run() {
try {
one.join();
System.out
.println("\nLetters\n-----------------------------------");
for (int i = 0; i < letters.length; i++) {
int a = rand.nextInt(3999);
System.out.printf(
"%s is sleeping for %d milliseconds.\n", Thread
.currentThread().getName(), a);
Thread.sleep(a);
System.out.println(Thread.currentThread().getName()
+ " is done sleeping.");
System.out.printf("current letter is %s\n", letters[i]);
}
} catch (InterruptedException e) {
System.out.printf("%s has been interrupted. How rude!",
Thread.currentThread().getName());
} finally {
System.out.printf("%s is now done. Finally!", Thread
.currentThread().getName());
}
}
};
three = new Thread() {
public void run() {
try {
int num = rand.nextInt(3999);
two.join();
if (num < 1000) {
System.out
.printf("\n%s is being interrupted because the random was %d and lower than 1000.",
Thread.currentThread().getName(), num);
Thread.sleep(2000);
Thread.currentThread().interrupt();
} else {
int a = rand.nextInt(3999);
System.out
.println("\nNegatives-----------------------------------\n");
System.out
.printf("the number was %s, Therefore, it will not be interrupted.",
num);
for (int i = 0; i < negatives.length; i++) {
System.out.printf(
"\n%s is sleeping for %d milliseconds.",
Thread.currentThread().getName(), a);
Thread.sleep(a);
System.out.printf("\n%s has finished sleeping.",
Thread.currentThread().getName());
System.out.printf(
"\ncurrent negative number is %s",
negatives[i]);
}
}
} catch (InterruptedException e) {
System.out.printf("\n%s has been interrupted. How rude!",
Thread.currentThread().getName());
} finally {
System.out.printf("\n%s is now done. Finally!", Thread
.currentThread().getName());
}
}
};
}
}
If I understand your question, then for Thread three you need to move the random number generation into the loop. Something like,
// int a = rand.nextInt(3999);
System.out.println("\nNegatives-----------------------------------");
System.out.printf("the number was %s and will not be interrupted.%n", num);
for (int i = 0; i < negatives.length; i++) {
int a = rand.nextInt(3999);
Without testing, I just checked Random's javadoc. There I find:
Instances of java.util.Random are threadsafe. However, the concurrent use of the same java.util.Random instance across threads may encounter contention and consequent poor performance. Consider instead using ThreadLocalRandom in multithreaded designs.
So you might check the ThreadLocalRandom, if it solves your problem.
Related
I am trying to learn Multi-threading and I am trying to print odd & even number using two thread but i am not sure how to synchronized the for loop and make it print from 1 to 10 in order.
public class Counter implements Runnable {
public static void main(String[] args) {
Thread t1 = new Thread(new Counter(1, " ODD")); // Thread 1 runs the Odd number
Thread t2 = new Thread(new Counter(0, " EVEN")); // Thread 2 runs the Even number
t1.start();
t2.start();
}
constructor:
int num; // gets the number
String name; // gets the name
public Counter(int i, String name) {
this.num = i;
this.name = name;
}
This is the Loop im using to create Odd and Even number and i dont know how to synchronized this loop.
public void printNum() {
synchronized (this) {
for (int j = this.num; j <= 10; j += 2) {
System.out.println(name + "-->" + j);
}
}
}
#Override
public void run() {
//this will run the printNum to the Threads
printNum();
}
Mb something like this
public class Counter implements Runnable{
#Override
public void run() {
try {
printNum();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args){
Thread t1 = new Thread(new Counter(1, " ODD")); // Thread 1 runs the Odd number
Thread t2 = new Thread(new Counter(0, " EVEN")); // Thread 2 runs the Even number
t2.start();
t1.start();
}
int num; // gets the number
String name; // gets the name
public Counter(int i, String name) {
this.num = i;
this.name = name;
}
public void printNum() throws InterruptedException {
synchronized (this) {
for (int j = this.num; j <= 10; j += 2) {
System.out.println(name + "-->" + j);
Thread.sleep(100);
}
}
}
}
Result:
public class HelloWorld {
public static void main(String[] args) {
counter e = new counter();
counter o = new counter();
e.neighbor = o;
o.neighbor = e;
e.wait = false;
o.wait = true;
e.count = 0;
o.count = 1;
Thread te = new Thread(e);
Thread to = new Thread(o);
te.start();
to.start();
}
static class counter implements Runnable{
public counter neighbor = null;
public boolean wait = false;
public int count = -1;
#Override
public void run(){
while (count <= 10){
if (!wait){
System.out.print("count = " + count + "\n");
count += 2;
wait = true;
neighbor.wait = false;
}
}
wait = true;
neighbor.wait = false;
}
}
}
Often when you have two threads interdependent on each other, like in these case where odd needs to wait until even has finished and vice versa, we need to establish some kind of relation in order for them to communicate with each other, the reason why your code wasn't working was because synchronize makes the thread wait until the other one has finished, in the loop however, the entire loop is considered one task and one thread will wait for the other to finish their loop first.
I want to print odd and even from 0 to 1000, the simple code are as follow using wait(),notifyAll() and synchronized to lock this instance. But the result stops printing 0 and 1, I am confused by this, did I miss something or the synchronized key-word isn't used proper? Can someone explain this, I've trying to figure it out for several hours,yet get nothing...
public class Main {
public static void main(String[] args) {
final int count = 1000;
new Thread() {
public void run() {
for (int j = 0; j <= count; j = j + 2) {
synchronized (this) {
System.out.println("Even thread:\t" + j);
notifyAll();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}.start();
new Thread() {
public void run() {
for (int j = 1; j <= count; j = j + 2)
synchronized (this) {
System.out.println("Odd thread:\t" + j);
notifyAll();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
The result is:
Even thread: 0
Odd thread: 1
and the JVM is still running,But I want to print is "0 1 2 3 4 5....". I don't know why it's wrong.
Solved ,thank you!!!
Explain:
And key-word "this" should refer to a specific object, I thought it refers to the outer class instance for granted. And what I do is just create a Object instance called obj , and synchronized,wait, notifyAll with this "obj". Just a problem of reference. I feel I am a little dumb...
I found I can't accept my answer within 2 days:"accept × You can accept your own answer in 2 days"
public class Main {
public static void main(String[] args) {
//String obj="";
Object obj=new Object();
final int count = 1000;
new Thread() {
public void run() {
for (int j = 0; j <= count; j = j + 2) {
synchronized (obj) {
System.out.println("Even thread:\t" + j);
if(j==1000) System.exit(0);//exit the JVM when prints 1000
obj.notifyAll();
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}.start();
new Thread() {
public void run() {
for (int j = 1; j <= count; j = j + 2)
synchronized (obj) {
System.out.println("Odd thread:\t" + j);
obj.notifyAll();
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
I have to take number of threads and the maximum number in a sequence from the user as input and I have to print the sequence from 0 to max number using the number of threads created , each thread should atleast print 1 number and no repetition of the same number is allowed.
my code is printing the sequence for each of the thread created and hence is repeating the numbers in the sequence.please tell me how can I have all threads print the seqeunce together and not individually so that I can have output like
max sequence-4
max threads-3
Thread 1-0
Thread 2-1
Thread 3-2
Thread 1-3
should the variable that is used to print the sequence be static?
Here is my code-
package com.demo;
import java.util.Scanner;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class SequencePrinter {
public static void main(String[] args) {
System.out.println("Enter the no.Of threads");
Scanner sn = new Scanner(System.in);
int n = sn.nextInt();// No. of Threads
Worker t1[] = new Worker[n];
System.out.println("Enter the max no.");
Scanner sc = new Scanner(System.in);
int r = sc.nextInt();// MAX no.
for (int i = 0; i < n; i++) {
t1[i] = new Worker();
}
for (int i = 0; i < n - 1; i++) {
t1[i].setNext(t1[i + 1]);
}
// Create the workers
// Worker w1 = new Worker();
// Worker w2 = new Worker();
// Worker w3 = new Worker();
// chain them in a round robin fashion
// w1.setNext(w2);
// w2.setNext(w3);
// w3.setNext(w1);
// for (int i = 0; i < t1.length; i++) {
//
// Thread t[i] = (Thread) new Thread(t1[i], "Thread-" + "i" + "-");
//
// }
// Create named threads for the workers
// Thread t1 = new Thread(w1, "Thread-1 - ");
// Thread t2 = new Thread(w2, "Thread-2 - ");
// Thread t3 = new Thread(w3, "Thread-3 - ");
// start the threads
for (int i = 0; i < t1.length; i++) {
t1[i].start();
}
// t1.start();
// t2.start();
// t3.start();
// Seed the first worker
t1[0].accept(0);
// t1[1].accept(1);
// try
// {
// t1[0].join();
// }
// catch(Exception e)
// {
// System.out.println("exception");
// }
for (int i = 0; i < t1.length; i++) {
t1[i].setVar(r);
}
}
}
class Worker extends Thread {
int r = 0;
int prnt = 0;
BlockingQueue<Integer> q = new LinkedBlockingQueue<Integer>();
Worker next = null; // next worker in the chain
public void setNext(Worker t) {
this.next = t;
}
public void accept(int i) {
q.add(i);
}
#Override
public String toString() {
// TODO Auto-generated method stub
return super.toString();
}
public void setVar(int i) {
r = i;// The Max no.to print
}
int[] ij = new int[r];
#Override
public synchronized void run() {
try {
int i = q.take(); // blocks till it receives a number
while (r != prnt) {
System.out.println(Thread.currentThread().getName() + ":" + prnt);
Thread.sleep(1000); // delay to slow the printing
if (next != null) {
next.accept(i + 1); // pass the next number to the next
}
// if(prnt==0|| prnt==1)
prnt = prnt + 1;
}
} catch (InterruptedException e) {
System.err.println(Thread.currentThread().getName() + " interrrupted.");
}
}
}
the code prints folllowing output
Enter the no.Of threads
2
Enter the max no.
4
Thread-0:0
Thread-0:1
Thread-1:0
Thread-1:1
Thread-0:2
Thread-0:3
Thread-1:2
Thread-1:3
Code is way more readable with variables and methods that have actual names.
import java.util.Scanner;
class SequencePrinter
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
System.out.print("number of threads: ");
final int numberOfThreads = scanner.nextInt();
System.out.print("maximum number to print: ");
final int maximumNumber = scanner.nextInt();
scanner.close();
for (int index = 0; index < numberOfThreads; ++index)
{
final int workerIndex = index;
Thread worker = new Thread(new Runnable()
{
public void run()
{
for (int number = workerIndex; number <= maximumNumber; number += numberOfThreads)
{
print(workerIndex, number);
}
}
});
worker.start();
}
}
synchronized
private static void print(int thread, int number)
{
System.out.println("thread " + thread + ", number " + number);
}
}
Because the idea of using an AtomicInteger was mentioned: that does not change much, and it certainly does not make the output sequentially ordered:
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;
class SequencePrinter
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
System.out.print("number of threads: ");
final int numberOfThreads = scanner.nextInt();
System.out.print("maximum number to print: ");
final int maximumNumber = scanner.nextInt();
scanner.close();
final AtomicInteger currentNumber = new AtomicInteger(0);
for (int index = 0; index < numberOfThreads; ++index)
{
final int workerIndex = index;
Thread worker = new Thread(new Runnable()
{
public void run()
{
while (true)
{
int number = currentNumber.getAndIncrement();
if (number <= maximumNumber)
{
print(workerIndex, number);
}
else
{
break;
}
}
}
});
worker.start();
}
}
synchronized
private static void print(int thread, int number)
{
System.out.println("thread " + thread + ", number " + number);
}
}
session:
number of threads: 3
maximum number to print: 11
thread 0, number 0
thread 2, number 2
thread 2, number 4
thread 2, number 5
thread 2, number 6
thread 2, number 7
thread 2, number 8
thread 2, number 9
thread 2, number 10
thread 2, number 11
thread 1, number 1
thread 0, number 3
The reason for this is that the AtomicInteger does not synchronize the output. It is simply another way to make sure that every number is printed just once. In the other example, this was achieved through a mathematical trick :)
This is not a solution, btw., because it is not guaranteed that every thread will eventually print anything. One thread could end up printing all the numbers.
What about using both Java8 and the Executor API capabilities ?
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;
public class Use {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
System.out.print("Number of threads: ");
int numberOfThreads = scanner.nextInt();
System.out.print("Maximum number to print: ");
int maximumNumber = scanner.nextInt();
ExecutorService pool = Executors.newFixedThreadPool(numberOfThreads);
Integer sequence = new Integer(0);
IntStream.range(0, maximumNumber)
.forEach(i -> pool.submit(() -> {
synchronized (sequence) {
System.out.println(Thread.currentThread().getName() + ": " + sequence++);
}
}));
pool.shutdown();
}
}
}
Note: as #starikoff said, this code doesn't guarantee the OP's requirement each thread should at least print 1 number.
Please look at class AtomicInteger. It fits your purposes perfectly and would make your code simpler. You won't have to worry about checking for duplication. All your threads will need to go is to get a value and check if it is less or equal to the max value and if so print it. Otherwise just terminate the thread. And yes you AtomicInteger variable will need to be static, so it will be the same instance available to to all your Threads.
I am trying to generate all permutations of some String in parallel using algorithm from here
(difference is that my code also handles Strings containing repetitive characters). I am using SynchrounousQueue for thread synchronization. Generator generates a permutation and Printer takes it and prints it. My code:
import java.util.ArrayList;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
public class PermBlockingQueue {
public static int printers = 4;
public static String str = "ABCD";
public static class Generator implements Runnable {
private final BlockingQueue q;
private final String pref;
public Generator(BlockingQueue q, String pref) {
this.q = q;
this.pref = pref;
}
public void permutations(String pref, String str) {
int n = str.length();
if (n == 0) {
try {
q.put(pref);
} catch (InterruptedException ex) { }
} else {
for (int i = 0; i < str.length(); i++) {
if (str.indexOf(str.charAt(i), i + 1) != -1) {
continue;
}
permutations(pref + str.charAt(i), str.substring(0, i) + str.substring(i + 1));
}
}
}
#Override
public void run() {
int k = str.indexOf(pref);
permutations(pref, str.substring(0, k) + str.substring(k + 1)));
//Sending messages for printers to quit
try {
for (int x = 0; x < printers; x++) {
q.put("");
}
} catch (InterruptedException ex) {
}
}
}
public static class Printer implements Runnable {
private final BlockingQueue q;
public Printer(BlockingQueue q) {
this.q = q;
}
#Override
public void run() {
try {
String permut;
while (!((permut = (String) q.take()).equals(""))) {
System.out.println(permut);
}
} catch (InterruptedException ex) {
}
}
}
public static void main(String[] args) throws InterruptedException {
ArrayList<Thread> threads = new ArrayList<>();
BlockingQueue q = new SynchronousQueue();
Thread th1 = new Thread(new Generator(q, "A"));
Thread th2 = new Thread(new Generator(q, "B"));
Thread th3 = new Thread(new Generator(q, "C"));
Thread th4 = new Thread(new Generator(q, "D"));
threads.add(th1);
threads.add(th2);
threads.add(th3);
threads.add(th4);
for (int i = 0; i < printers; i++) {
threads.add(new Thread(new Printer(q)));
}
for (Thread th : threads.toArray(new Thread[threads.size()])) {
th.start();
}
for (Thread th : threads.toArray(new Thread[threads.size()])) {
th.join();
}
}
}
In sequential program method permutations(String pref, String str) works as expected. As far as synchronization goes, there are no problems as long as I am not using recursive method. In this program however, I am using recursive method and it deadlocks. I am guessing that Generator locks itself because multiple values are returned to it and further more, nothing gets printed. Also, if I put print statement in permutations method before return statement,
if (n == 0) {
System.out.println(pref);
return pref;
}
I get the expected output, which in case of "ABCD" is (4! = 24 permutations):
ABCD
ABDC
ACBD
....
DBAC
DBCA
DCAB
DCBA
Of course these values are not printed by Printers who are waiting for input from Generators and program is deadlocked.
So what exactly happens with recursive method here? And most importantly, how do I approach this kind of problem?
Thank you.
Edit: I've changed my code a little bit, considering the fact, that
q.put(permutations(pref, str.substring(0, k) + str.substring(k + 1)));
didn't really made much of a sense (correct me, if I'm wrong). This is because, in my mind, it creates a ambiguity as to which permutation should be put in SynchronousQueue, as single call to permutation yields more than one permutation (at least in my example).
Now I'm putting permutations into queue inside permutations method, whereas in Generators' run() I only call permutations. This gives better results: instead of no permutations getting printed, some are printed. This 'some' varies with each execution and program still gets deadlocked.
This program in Java creates a list of 15 numbers and creates 3 threads to search for the maximum in a given interval. I want to create another thread that takes those 3 numbers and get the maximum. but i don't know how to get those values in the other thread.
public class apple implements Runnable{
String name;
int time, number, first, last, maximum;
int[] array = {12, 32, 54 ,64, 656, 756, 765 ,43, 34, 54,5 ,45 ,6 , 5, 65};
public apple(String s, int f, int l){
name = s;
first = f;
last = l;
maximum = array[0];
}
public void run(){
try{
for(int i = first; i < last; i++ )
{
if(maximum < array[i])
{
maximum = array[i];
}
}
System.out.println("Thread"+ name + "maximum = " + maximum);
}catch(Exception e){}
}
public static void main(String[] args){
Thread t1 = new Thread(new apple("1 ", 0, 5));
Thread t2 = new Thread(new apple("2 ", 5, 10 ));
Thread t3 = new Thread(new apple("3 ", 10, 15));
try{
t1.start();
t2.start();
t3.start();
}catch(Exception e){}
}
}
Here is how ExecutorService and ExecutorCompletionService can solve it:
public class MaxFinder {
private int[] values;
private int threadsCount;
public MaxFinder(int[] values, int threadsCount) {
this.values = values;
this.threadsCount = threadsCount;
}
public int find() throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(threadsCount);
ExecutorCompletionService<Integer> cs = new ExecutorCompletionService<Integer>(executor);
// Split the work
int perThread = values.length / threadsCount;
int from = 0;
for(int i = 0; i < threadsCount - 1; i++) {
cs.submit(new Worker(from, from + perThread));
from += perThread;
}
cs.submit(new Worker(from,values.length));
// Start collecting results as they arrive
int globalMax = values[0];
try {
for(int i = 0; i < threadsCount; i++){
int v = cs.take().get();
if (v > globalMax)
globalMax = v;
}
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
executor.shutdown();
return globalMax;
}
private class Worker implements Callable<Integer> {
private int fromIndex;
private int toIndex;
public Worker(int fromIndex, int toIndex) {
this.fromIndex = fromIndex;
this.toIndex = toIndex;
}
#Override
public Integer call() {
int max = values[0];
for(int i = fromIndex; i<toIndex; i++){
if (values[i] > max)
max = values[i];
}
return max;
}
}
}
In this solution, N threads work concurrently, each on its portion of the array. The caller thread is responsible for gathering the local maximums as they arrive, and find the global maximum. This solution uses some non-trivial concurrency tools from java.util.concurrent package.
If you prefer a solution that only uses primitive synchronization tools, then you should use a synchronized block in the worker threads, that sets the maximum in some data member and then notifies the collector thread. The collector thread should be in a loop, waiting for notification and then examining the new number, and updating the global maximum if needed. This "consumer producer" model requires careful synchronization.
Based on the code you have, the simplest solution is to join the main thread to each instance thread and then get the max value from them for comparison purposes. Like so:
int globalMax;
try{
t1.start();
t2.start();
t3.start();
t1.join();
globalMax = t1.maximum;
t2.join();
if (t2.maximum > globalMax) {
globalMax = t2.maximum;
}
t3.join();
if (t3.maximum > globalMax) {
globalMax = t3.maximum;
}
} catch(Exception e){
}
Instead of implementing Runnable, try implementing Callable, which is capable of returning a result. The tutorial given here is a good source for describing how to do this.
Another approach to your problem could be to create an object which each apple instance (not sure why you've called it this) could register its maximum with the object. This new class could be passed into each apple constructor, then the apple could call a method, passing its own maximum into this.
For instance:
public class MaximumOfMaximumsFinder implements Runnable {
private List<Integer> maximums = new ArrayList<Integer>();
public void registerSingleMaximum(Integer max) {
maximums.add(max);
}
public void run() {
// use similar logic to find the maximum
}
}
There are several issues around making sure this is coordinated with the other threads, I'll leave this to you, since there's some interesting things to think about.