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.
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 will input some number to calculates sum of Factorial series,
like if i put 5, output will be 1!+2!+3!+4!+5!, but calculating processing could be heavy so i want to use multiple treads that calculates each factorial.. means thread1 cals 1!, thread2 cals 2!...
i used arrays of threads but can't sync them in propel results. and can't find the way to sum these results.
i wrote codes...
public class Calthread extends Thread{
private int num=1;
public Calthread(int num) {
this.num = num;
}
public void run() {
int dft = 1;
for(int i=1; i<=num; i++) {
dft = dft*i;
}
System.out.println(num + "! result :" + dft);
}
}
this is for 1 thread
for main class
public class calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("input number>>");
int k = scanner.nextInt(); //input 'k'
int sum = 0;
Calthread[] cal = new Calthread[k]; // make threads number of 'k'
for(int i = 0; i<k; i++) {
cal[i] = new Calthread(i+1);
cal[i].start();
}
}
}
how can I Sync them and print the sum of all?
To return value from thread you should use Callable instead of Runnable:
public class Calthread implements Callable<Integer> {
private int num = 1;
public Calthread(int num) {
this.num = num;
}
#Override
public Integer call() {
int dft = 1;
for (int i = 1; i <= num; i++) {
dft = dft * i;
}
return dft;
}
}
And in the main class:
public class Calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("input number>>");
int k = scanner.nextInt(); //input 'k'
int sum = 0;
// Make threads number of 'k'. Here we use List instead of array because there is such contract in ExecutorService
List<Calthread> cal = new ArrayList<>(k);
// Create thread pool with fixed number of threads
ExecutorService service = Executors.newFixedThreadPool(k);
// Add all Callable task in one collection
for (int i = 0; i < k; i++) {
cal.add(new Calthread(i+1));
}
try {
// Invoke all Callable task and get List with results
List<Future<Integer>> results = service.invokeAll(cal);
// Future::get is blocking method. It waits result.
for (Future<Integer> result : results) {
sum += result.get();
}
} catch (InterruptedException | ExecutionException e) {
System.out.println("Something went wrong");
e.printStackTrace();
}
System.out.println("Result: " + sum);
// We need to shutdown our service
service.shutdown();
}
}
I've made a class that counts words in given files within the same directory. Seeing as the files are very large, I've decided to achieve the count of multiple files using multiple threads.
When running the DriverClass as specified below, it get's stuck at thread one.
What am I doing wrong? As I'm iterating over queue.take(), one would expect the parser to wait for something to retrieve and move on. Getting stuck at thread 1 makes me suspect an error when putting() into the queue.
Thank's, in advance!
DriverClass:
public class WordCountTest {
public static void main(String[] args){
if (args.length<1){
System.out.println("Please specify, atleast, one file");
}
BlockingQueue<Integer> threadQueue = new LinkedBlockingQueue<>();
Runnable r;
Thread t;
for (int i = 0; i<args.length; i++){
r = new WordCount(args[i], threadQueue);
t = new Thread(r);
t.start();
int total = 0;
for (int k = 0; k<args.length; k++){
try {
total += threadQueue.take();
} catch (InterruptedException e){
}
}
System.out.println("Total wordcount: " + total);
}
}
}
WordCountClass:
public class WordCount implements Runnable {
private int myId = 0;
private String _file;
private BlockingQueue<Integer> _queue;
private static int id = 0;
public WordCount(String file, BlockingQueue<Integer> queue){
_queue = queue;
_file = file;
myId = ++id;
}
#Override
public void run() {
System.out.println("Thread " + myId + " running");
try {
_queue.put(countWord(_file));
} catch (InterruptedException e){
}
}
public int countWord(String file){
int count = 0;
try {
Scanner in = new Scanner(new FileReader(file));
while (in.hasNext()){
count++;
in.next();
}
} catch (IOException e){
System.out.println("File," + file + ",not found");
}
return count;
}
}
The problem is that you're using a nested loop, when you should be using two separate loops: one to start the WordCounts, another to collect the results, something like
public class WordCountTest {
public static void main(String[] args){
Queue<Integer> threadQueue = new ConcurrentLinkedQueue<>();
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
CountDownLatch latch = new CountDownLatch(args.length);
for (int i = 0; i<args.length; i++){
CompletableFuture.runAsync(new WordCount(args[i], threadQueue), executor)
.thenRunAsync(latch.countDown(), executor);
}
latch.await();
int sum = 0;
for(Integer i : threadQueue) {
sum += i;
}
}
}
Or however you want to implement it, the point being that you shouldn't start collecting results until all of the WordCounts have started.
You are waiting for all the results after the first thread is started. Perhaps you intended to wait for the results after all the threads have started.
Note: if you create more threads than you have CPUs its likely to be slower. I suggest using a fixed thread pool instead.
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.
I want that when the dec() calls it must make two decrements and then its decremented value will pass to inc() and then increment by 1 so that a time come when the decremented value equal to zero and it stops the program..
Code is here
package thread_array;
import java.io.*;
import java.lang.Thread;
import java.util.Scanner;
class A extends Thread {
public static int count;
public static int a, b;
Thread t;
public static int i;
A(int i) {
synchronized (this) {
a = i;
System.out.println("Value of a " + a);
count = a;
System.out.println("Value of count " + count);
t = new Thread(this);
t.start();
new B(count);
}
}
#Override
public void run() {
inc();
}
public synchronized void inc() {
try {
if (count != 0) {
synchronized (this) {
System.out.println("Before Incrementing pre " + count);
++count;
System.out.println("Incrementing pre " + count);
System.out.println("Incrementing in value of p " + count);
Thread.sleep(2000);
}
} else {
System.out.println("Count values cannot be negative");
}
} catch (InterruptedException e) {
// ignore this
}
}
}
class B extends Thread {
public static int count;
public static int a, b;
Thread t;
public static int i;
B(int i) {
a = i;
System.out.println("Value of a in class B " + a);
count = a;
t = new Thread(this);
t.start();
new A(count);
}
#Override
public void run() {
dec();
}
public synchronized void dec() {
try {
if (count != 0) {
synchronized (this) {
System.out.println("Before Decrementing pre " + count);
b = count--;
System.out.println("Decrementing first " + count);
count--;
System.out.println("Value of second count: " + count);
Thread.sleep(1000);
System.out.println("p out" + count);
}
} else {
System.out.println("Count values cannot be negative");
}
} catch (InterruptedException e) {
// ignore exception
}
}
}
class Thread_array extends Thread implements Runnable {
public static void main(String[] args) throws IOException, InterruptedException {
int z;
System.out.print("Enter your desired number: ");
Scanner input = new Scanner(System.in);
int dj = input.nextInt();
int[] array = new int[dj];
for (z = 0; z < array.length; z++) {
array[z] = 0;
System.out.print(" " + array[z]);
}
System.out.println();
new B(dj);
new A(dj);
}
I don't see how your program does what you want; every new A() creates a new B() which creates another new A(). Your code seems to loop spawning objects and threads! Did you omit a guard that would not spawn additional objects when the passed parameter was non-positive?
Enter your desired number: 4
0 0 0 0
Value of a in class B 4
Before Decrementing pre 4
Decrementing first 3
Value of second count: 2
p out2
Value of a 2
Value of count 2
Value of a in class B 2
Before Decrementing pre 2
Decrementing first 1
Value of second count: 0
p out0
Value of a 1
Value of count 1
Value of a in class B 1
Before Decrementing pre 1
Decrementing first 0
Value of second count: -1
p out-1
Value of a 0
Value of count 0
Value of a in class B 0
Count values cannot be negative
Value of a 0
Value of count 0
Value of a in class B 0
Count values cannot be negative
...
the fact that yout t.start() calls are not followed by t.join() calls makes me believe your code is at best non-deterministic.