How can i get multi thread parallel calculator (factorial sum) - java

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();
}
}

Related

Confusion regarding threads and thread safety

To understand the concept of threads better, we are supposed to use a Number object that can be increased, decreased, squared and rooted via it's methods. It's only attribute is a double number (initialized as number=1).
So if i instantiate the Number object and call increment(), decrement(), square() and root() 100000000 times to that number object, the number attribute is 1 again (as expected).
Now the problem is that we are supposed to instantiate two thread objects, one calling the increase/decrease 100000000 times and the other one calling square/root 100000000 times.
According to our teacher the result would be inconsistency, i.E getting 0 instead of 1 as the result, but in my program it just gives me infinity or 1 depending on wether or not i am using synchronized() in the Thread class.
public class Calculation {
public static void main(String[] args) throws InterruptedException {
Number num = new Number();
Number num1 = new Number();
for (int i = 0; i < 100000000; i++) {
num.increment();
}
for (int i = 0; i < 100000000; i++) {
num.decrement();
}
for (int i = 0; i < 100000000; i++) {
num.square();
}
for (int i = 0; i < 100000000; i++) {
num.root();
}
System.out.println(num.getNumber());
CalcThread t1 = new CalcThread(num1, true);
CalcThread t2 = new CalcThread(num1, false);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(num1.getNumber());
}
}
public class CalcThread extends Thread {
public Number num;
public boolean decision;
public CalcThread(Number num, boolean decision) {
this.num = num;
this.decision = decision;
}
#Override
public void run() {
synchronized(num) {
if (this.decision) {
for (int i = 0; i < 100000000; i++) {
num.square();
}
for (int i = 0; i < 100000000; i++) {
num.root();
}
} else {
for (int i = 0; i < 100000000; i++) {
num.increment();
}
for (int i = 0; i < 100000000; i++) {
num.decrement();
}
}
}
}
}
public class Number {
double number;
public Number() {
this.number = 1;
}
public void increment() {
this.number++;
}
public void decrement() {
this.number--;
}
public void square() {
this.number = this.number * this.number;
}
public void root() {
this.number = Math.sqrt(this.number);
}
public double getNumber() {
return number;
}
public void setNumber(double number) {
this.number = number;
}
}
Getting infinity when leaving synchronized out makes sense because it is increasing while squaring the number at the same time, so the number will soon be too large to fit the double type size right?
How do i get the inconsistency my teacher was talking about?
Thank you for your help in advance.

Sum of all the elements in an array with ExecutorService pool not working

I am trying to understand ExecutorService and i want to do the sum of all the elements of an array. I did two methods, one that makes the sum serially (just a for loop that sums all the elements) and other concurrently with a pool. My problem is that the total sum from using ExecutorService is off with the serial sum almost all the time, sometimes even just by one.
package sumArregloConc;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class SumaArregloMain {
private final static int cantElem = 1000;
private static ExecutorService tpool = Executors.newCachedThreadPool();
public static void main(String[] args)
{
int[] arreglo = generarArreglo(cantElem); //generate the array with random numbers
System.out.println(sumaSerial(arreglo));
System.out.println(sumaConcurrente(arreglo));
}
public static int sumaSerial(int[] arreglo)
{
int suma = 0;
for(int i =0; i< arreglo.length; i++)
{
suma += arreglo[i];
}
return suma;
}
public static int sumaConcurrente(int[] arreglo)
{
AtomicInteger total = new AtomicInteger(0);
for(int i = 1 ; i < cantElem; i++){
int a = arreglo[i];
Thread thread = new Thread(new Runnable(){
public void run() {
int res = a;
total.addAndGet(res);
return;
}});
tpool.submit(thread);
}
tpool.shutdown(); //wait for everything to finish
return total.get();
}
public static int[] generarArreglo(int cantElem)
{
int[] arreglo = new int[cantElem];
Random rand = new Random();
for(int i = 0; i < cantElem; i++)
{
arreglo[i] = rand.nextInt(10);
}
return arreglo;
}
}
Can someone tell what is wrong?
Found the error. First what Eric said about awaitTermination and Runnable, but the main bug was just that the loop started at i = 1 instead of i = 0, silly mistake.
public static int sumaConcurrente(int[] arreglo)
{
AtomicInteger total = new AtomicInteger(0);
for(int i = 0 ; i < cantElem; i++){
int a = arreglo[i];
tpool.submit(new Runnable(){
public void run() {
total.addAndGet(a);
return;
}
});
}
tpool.shutdown(); //wait for everything to finish
try {
tpool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
}
return total.get();
}

What is wrong with the my semaphore application?

The program's aim is to simulate that multiple users add a number to the buffer from 0 to n. Then print the sum of numbers in the buffer. When I run the program, it seems that the threads never end. However, the thread will finish when I run the program in debug mode of Idea and step line by line. Also, I do not exactly know where I need to use my semaphore method P() and V() for mutual exclusion.
Version: JDK 8. I cannot use semaphore in the library.
Main.java
Buffer b = new Buffer(bufferSize);
ArrayList<user> us = new ArrayList<>();
for(int i = 0; i < num_users; i++) us.add(new user(i, elements, b));
ArrayList<Thread> th = new ArrayList<>();
for(int i = 0; i < num_users; i++)
{
th.add(new Thread(us.get(i)));
th.get(i).start();
}
user.java
public class user implements Runnable
{
private int id;
private int num_elements;
private semaphore mutex = new semaphore(1 );
public static Buffer buf;
public user(int i, int el, Buffer b)
{id = i; num_elements = el; buf = b;}
public void add_elements()
{//Add element to buffer, element value iterates from 0, 1, 2 .... num_elements
mutex.P();
int n = 0;
while (num_elements > 0)
{
buf.add(new Integer(n));
n++;
num_elements--;
}
mutex.V();
}
public void run()
{
add_elements();
}
}
Buffer.java
public class Buffer
{
private LinkedList<Object> buf_list;
private int elements; //Number of elements currently on the queue
private int buf_size; //Maximum number of elements allowed on queue
private semaphore mutex = new semaphore(1);
public Buffer(int n) //Queue creation, with n indicating the maximum capacity
{
buf_list = new LinkedList<Object>();
elements = 0;
buf_size = n;
}
public void add(Integer n)
{
mutex.P();
buf_list.add(n);
elements++;
mutex.V();
}
public void finalSummation()
{
if (elements == buf_size)
{
mutex.P();
int sum = 0;
for (Object n : buf_list)
sum += ((Integer)n).intValue();
mutex.V();
System.out.println("Count total: " + sum);
}
}
}
semaphore.java
public class semaphore
{
private int count = 0;
public semaphore(int init_count)
{
count = init_count;
}
public synchronized void P()
{
count -= 1;
while (count < 0)
{
try {
wait();
} catch (InterruptedException e) {
System.out.println("Error");
System.exit(-1);
}
}
}
public synchronized void V()
{
count += 1;
notifyAll();
}
}
I expect it will print the sum of buffer numbers, but the thread may not finish.
There are a few things that stand out as issues here.
1) your code is never calling the finalSummation method. So the "printing" of the result will never happen.
2) Buffer and each user are all creating their own semaphores. If you are attempting to allow multiple threads to update Buffer without colliding then you need to share the same semaphore. Remove the semaphore and the usage of it from the user class. Just let the Buffer instance control only one update at a time with its semaphore.
3) You don't need to check the semaphore in the finalSummation method. Presumably, all threads are done at that point. And to enforce that ...
4) Put code like this at the end of main
for(int i = 0; i < num_users; i++) {
th.get(i).join();
}
b.finalSummation();
5) A semaphore should manage a number of permits. Your semaphore is managing the number of instances waiting - that is a pretty much an irrelevant number for a semaphore. Change your P() and V() to acquire() and release() to be consistent with the pattern.
public static class semaphore {
private int permits = 0;
public semaphore(int permits) {
this.permits = permits;
}
public synchronized void acquire() {
while (permits < 1) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Error");
System.exit(-1);
}
}
permits--;
}
public void release() {
synchronized (this) {
permits += 1;
notifyAll();
}
}
}
I have put it together using the above answer if that helps. Please select above answer as the right answer.
import java.util.ArrayList;
import java.util.LinkedList;
public class Main {
// assumed values
private static final int bufferSize = 5;
private static final int num_users = 10;
private static final int elements = 5;
public static void main(String[] args) {
Buffer b = new Buffer(bufferSize);
ArrayList<User> us = new ArrayList<>();
for(int i = 0; i < num_users; i++) us.add(new User(i, elements, b));
ArrayList<Thread> th = new ArrayList<>();
for(int i = 0; i < num_users; i++)
{
th.add(new Thread(us.get(i)));
th.get(i).start();
}
for(int i = 0; i < num_users; i++) {
try {
th.get(i).join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
b.finalSummation();
System.out.println("Exiting");
}
}
class User implements Runnable
{
private int id;
private int num_elements;
public static Buffer buf;
public User(int i, int el, Buffer b)
{id = i; num_elements = el; buf = b;}
public void add_elements()
{//Add element to buffer, element value iterates from 0, 1, 2 .... num_elements
int n = 0;
while (num_elements > 0)
{
buf.add(new Integer(n));
n++;
num_elements--;
}
}
public void run()
{
add_elements();
}
}
class Buffer
{
private LinkedList<Object> buf_list;
private int elements; //Number of elements currently on the queue
private int buf_size; //Maximum number of elements allowed on queue
private Semaphore mutex ;
public Buffer(int n) //Queue creation, with n indicating the maximum capacity
{
buf_list = new LinkedList<Object>();
elements = 0;
buf_size = n;
mutex = new Semaphore(buf_size);
}
public synchronized void add(Integer n)
{
mutex.acquire();
buf_list.add(n);
elements++;
mutex.release();
}
public void finalSummation()
{
int sum = 0;
System.out.println(buf_list);
for (Object n : buf_list)
sum += ((Integer)n).intValue();
System.out.println("Count total: " + sum);
}
}
class Semaphore {
private int permits = 0;
public Semaphore(int permits) {
this.permits = permits;
}
public synchronized void acquire() {
while (permits < 1) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Error");
System.exit(-1);
}
}
permits--;
}
public void release() {
synchronized (this) {
permits += 1;
notifyAll();
}
}
}

Display sequence using multiple threads

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.

Division of a task to threads - multi threading

I want to generate pairs from a given large pool of numbers. I am using two for loops and threads. My function getAllPairs() in the code generates apairs with a given array of numbers.
I have an array of length 1000. With one thread, output time is nearly 15 sec. Now I want to use 5-6 threads and reduce this output time.I am stuck at dividing this task equally to five threads.If not threads,how to decrease the output time?
Solution with threads is appreciated since I put a lot of time learning multithreading. I would like to implement it.
import java.util.*;
class Pair {
public int x, y;
public Pair(int x, int y) {
this.x = x;
this.y = y;
}
#Override
public String toString(){
return " ( " + x + " ," + y + " ) " ;
}
}
class selectPairs{
private int[] array;
private List<Pair> totalPairs ;
public selectPairs(int[] arr){
array = arr;
}
//set Method
public void settotalPairs(List<Pair> pieces){
totalPairs = pieces;
}
//get Method
public List<Pair> gettotalPairs(){
return totalPairs;
}
// Method to generate pairs
public List<Pair> getAllPairs() {
List<Pair> pairs = new ArrayList<Pair>();
int total = array.length;
for(int i=0; i < total; i++) {
int num1 = array[i];
for(int j=i+1; j < total; j++) {
int num2 = array[j];
pairs.add(new Pair(num1,num2));
}
}
return pairs;
}
}
// Thread class
class ThreadPairs extends Thread {
private Thread t;
selectPairs SP;
ThreadPairs(selectPairs sp){
SP = sp;
}
public void run() {
synchronized(SP) {
List<Pair> PAIRS = SP.getAllPairs();
SP.settotalPairs(PAIRS);
}
}
}
public class TestThread {
public static void main(String args[]) {
int[] a = new int[1000];
for (int i = 0; i < a.length; i++) {
a[i] = i ;
}
selectPairs ob = new selectPairs(a);
ThreadPairs T = new ThreadPairs( ob );
T.start();
while (true) {
try {
T.join();
break;
}
catch(Exception e){
}
}
List<Pair> Total = new ArrayList<Pair>() ;
List<Pair> Temp1 = ob.gettotalPairs();
Total.addAll(Temp1);
System.out.println(Total);
}
}
A solution with a thread-pool, a task split strategy and it collects all results:
public class SelectPairs {
private static final int NUM_THREADS = 8;
private int[] array;
public SelectPairs(int[] arr) {
array = arr;
}
// A splitting task strategy
public List<Pair> getPartialPairs(int threadIndex, int numThreads) {
List<Pair> pairs = new ArrayList<Pair>();
int total = array.length;
for (int i = threadIndex; i < total; i += numThreads) {
int num1 = array[i];
for (int j = i + 1; j < total; j++) {
int num2 = array[j];
pairs.add(new Pair(num1, num2));
}
}
return pairs;
}
// To use Callables or Runnables are better than extends a Thread.
public static class PartialPairsCall implements Callable<List<Pair>> {
private int thread;
private int totalThreads;
private SelectPairs selectPairs;
public PartialPairsCall(int thread, int totalThreads, SelectPairs selectPairs) {
this.thread = thread;
this.totalThreads = totalThreads;
this.selectPairs = selectPairs;
}
#Override
public List<Pair> call() throws Exception {
return selectPairs.getPartialPairs(thread, totalThreads);
}
}
public static void main(String[] args) throws Exception {
int[] a = new int[1000];
for (int i = 0; i < a.length; i++) {
a[i] = i;
}
SelectPairs sp = new SelectPairs(a);
// Create a thread pool
ExecutorService es = Executors.newFixedThreadPool(NUM_THREADS);
List<Future<List<Pair>>> futures = new ArrayList<>(NUM_THREADS);
// Submit task to every thread:
for (int i = 0; i < NUM_THREADS; i++) {
futures.add(es.submit(new PartialPairsCall(i, NUM_THREADS, sp)));
}
// Collect the results:
List<Pair> result = new ArrayList<>(a.length * (a.length - 1));
for (Future<List<Pair>> future : futures) {
result.addAll(future.get());
}
// Shutdown thread pool
es.shutdown();
System.out.println("result: " + result.size());
}
}
regarding the framework of multithreading, you can implement ThreadPoolExecutor as was suggested in a comment.
Regarding splitting the workload, it seems that the key is splitting the iteration on the array which is achievable if you give the Runnable task a start and end index to iterate over.

Categories

Resources