Thread Pool using Executor Framrwork - java

I am using an the executor framework to create multiple instances of the Fadder object and print the result. I am trying to learn how to use multiple threads to get a task done faster. The problem I am having is that the numbers print in a random order each time I run the program. I thought creating a new object for each iteration of the loop would solve that problem but it still prints the number in a "random" order. Is there any way I can guarantee that the threads print in the order they are suppose to run? like 1,2,3,4,5. Thanks
package fadder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Fadder {
private final int n;
Fadder(int n){
//initialize Fadder
this.n = n;
}
Fadder add(int m){
//create new Fadder
return new Fadder(n+m);
}
public static void main(String[] args) {
int threadnum = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(threadnum);
Fadder MyAdder = new Fadder(1);
for (int i = 0; i < 5; i+=1 ) {
int index = i;
//lambda function to print Fadder
executor.submit(() -> {
System.out.println(String.valueOf(MyAdder.add(index)));
});
}
executor.shutdown();
}
}

You cannot garantee the sequence in which many threads will process your code.
But, will parallel stream, you can. See below :
Stream<Integer> stream = Stream.iterate(1, i->i+1).limit(5) ;
stream.parallel().forEachOrdered(System.out::println);

Related

How to correctly use the Threads

I have the following task :
Create Class called: ElementsProvider(int n, List elements) that will provide N random elements into given list.
Elements Provider will be an thread.
Try create 4 instances, each of this instance will add 1000 random elements into the list.
start all instances at once and wait until they end.
print list size.
And here is what is did ,
Main:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class ElementsProvider implements Runnable{
private final List<Integer> list;
private final int n;
public ElementsProvider(List<Integer> list, int n){
this.list = list;
this.n = n;
}
#Override
public void run() {
Random random = new Random();
for (int i = 0; i < n; i++) {
list.add(random.nextInt());
}
}
public static void main(String[] args) throws InterruptedException {
List<Integer> list = new ArrayList<>();
int n = 1000;
ElementsProvider e1 = new ElementsProvider(list, n);
ElementsProvider e2 = new ElementsProvider(list, n);
ElementsProvider e3 = new ElementsProvider(list, n);
ElementsProvider e4 = new ElementsProvider(list, n);
Thread t1 = new Thread(e1);
Thread t2 = new Thread(e2);
Thread t3 = new Thread(e3);
Thread t4 = new Thread(e4);
t1.start();
t2.start();
t3.start();
t4.start();
t1.join();
t2.join();
t3.join();
t4.join();
System.out.println(list);
}
}
Apparently I got that the task is not ok.
Feedback that I got is :
wrong, try to print list size, it will be different each time You run the program.
Can someone point me where I am mistaking please?
You proposed this change in a comment on your original question, above:
#Override
public void run() {
synchronized (ElementsProvider.class) {
Random random = new Random();
for (int i = 0; i < n; i++) {
list.add(random.nextInt());
}
}
}
O.K., That will ensure that your program always prints the correct answer, but it does so by making your program effectively single-threaded. When you put the entire body of the threads' run() method in a single synchronized block, you prevent them from running concurrently. But, running concurrently is the only reason to use threads.
You need to synchronize a smaller part of the code. The only variable that the threads share is the list. There is no reason for new Random() to be inside the synchronized block, and there is no reason for random.nextInt() to be inside it. The only thing that needs to be inside the synchronized block is the list.add() call.
I'd add a static semaphore to the your ElementsProvider class:
public class ElementsProvider implements Runnable {
private final List<Integer> list;
private final int n;
private static Semaphore semaphore = new Semaphore(1);
public ElementsProvider(List<Integer> list, int n) {
this.list = list;
this.n = n;
}
#Override
public void run() {
Random random = new Random();
List<Integer> l = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
l.add(random.nextInt());
}
try {
semaphore.acquire();
System.out.println("Adding " + l.size() + " elements to list");
list.addAll(l);
} catch (Exception e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
}

Improve calculation time in parallel mode

I am new in the multithreading in Java, so I have a question about how to reduce calculation time in this example, without using Executors, Frameworks, etc, only plain threads?
public static void main(String[] args) throws TestException {
Set<Double> res = new HashSet<>();
for (int i = 0; i < TestConsts.N; i++) {
res.addAll(TestCalc.calculate(i));
}
System.out.println(res);
}
And there is calculation method:
private static final Random rnd = new Random();
public static Set<Double> calculate(int num) throws TestException {
// Emulates calculation delay time.
try {
Thread.sleep(rnd.nextInt(1000) + 1);
}
catch (InterruptedException e) {
throw new TestException("Execution error.", e);
}
Set<Double> res = new HashSet<>();
int n = rnd.nextInt(num + 1) + 1;
for (int j = 0; j < n; j++) {
res.add(rnd.nextDouble());
}
return res;
}
The reason for not using any frameworks is that I want to understand the original multithreading.
Thanks you in advance.
Try to create a class that extends Thread or implements Runnable, add the details on the calculate() method to the run() method of the new class.
Now in the for loop of main function create new threads of type of the new class and start() them.
Also you need to synchronize the threads.
Reference
I will try to answer on a conceptual level:
You could spawn a Thread for each task
You could spawn n threads that use a (synchronized) Queue<Task> to obtain more work
You will have to synchronize whenever a thread finishes its part.

Java threading issue?

I am wondering why the result is not 400 000. There are two threads why does it gets blocked?
class IntCell {
private int n = 0;
public int getN() {return n;}
public void setN(int n) {this.n = n;}
}
class Count extends Thread {
private static IntCell n = new IntCell();
#Override public void run() {
int temp;
for (int i = 0; i < 200000; i++) {
temp = n.getN();
n.setN(temp + 1);
}
}
public static void main(String[] args) {
Count p = new Count();
Count q = new Count();
p.start();
q.start();
try { p.join(); q.join(); }
catch (InterruptedException e) { }
System.out.println("The value of n is " + n.getN());
}
}
Why there is so problem with that?
Because the way you increment your variable is not an atomic operation indeed to increment it you:
Get the previous value
Add one to this value
Set a new value
They are 3 operations not done atomically you should either us a synchronized block or use an AtomicInteger instead.
With a synchronized block it would be something like:
synchronized (n) {
temp = n.getN();
n.setN(temp + 1);
}
With an AtomicInteger you will need to rewrite your code as next:
class IntCell {
private final AtomicInteger n = new AtomicInteger();
public int getN() {return n.get();}
public void incrementN(int n) {this.n.addAndGet(n);}
}
for (int i = 0; i < 200000; i++) {
n.incrementN(1);
}
The approach with an AtomicInteger is non blocking so it will be faster
When two threads access one object at the same time, they interfere with each other, and the result is not deterministic. For example, imagine that p reads the value of n and gets, say, 0, then q reads the same value and gets 0 too, then p sets value to 1 and q also sets it to 1 (because it still thinks that it has value 0). Now the value of n is increased by 1, even though both counters "incremented" it once. You need to use synchronized block to make sure the counters won't interfere with each other. See https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html for more.
The problem here is that you allow for race conditions. Consider the block inside the loop:
temp = n.getN();
n.setN(temp + 1);
The code context switch between the time you get the current N and by the time you increment it, making you set an "old" value. One way around this is to ensure the inner part of the loop runs in a synchronized block:
for (int i = 0; i < 200000; i++) {
synchronized (n) { / Here!
temp = n.getN();
n.setN(temp + 1);
}
}

Multiple Threads spawning multiple threads and how to wait for child Threads

I have two arrays abc[100] and def[1000] and I have to find an array xyz[100] , where xyz[i] = minDistance(abc[i],def) i.e for every element in abc i have to find a corresponding nearest element in def and set in xyz.
For this I am using threads at two level . At first level I am creating threads for every 10 points in abc and at second level for each I am creating child threads for every 100 points in def. Below is my implementation .
My questions are
How Can I wait for the child threads of abc(i.e def threads) . I have gone through the java join method but not able to figure out on how to use this .
Can i use Cyclic Barrier in this case.
The actual data is in the magnitude 1000s for abc and 10000 for def and I haven't used threads before ,so are there any issues that can happen with this implementation . Also I have seen use of ThreadPoolExecutor instead of the FixedThreads in some examples but couldnt figure out how much ThreadPoolExecutor will have.
1. DistanceCalculation
public class MinDistanceCalculation {
public static List<double[]> xyz = new Vector<double[]>();
public void method1(){
double[][] abc = new double[100][7];
double[][] def = new double[1000][7];
ExecutorService executorService = Executors.newFixedThreadPool(10);
for(int i = 0 ; i < abc.length ; i = i*10){
executorService.execute(new MainThread(abc,i , i*10 , def));
}
}
}
2 . Main Thread / abc Threads
public class MainThread implements Runnable{
double[][] abc = null;
double[][] def = null;
int startPos = 0;
int endPos = 0;
public MainThread(double[][] abc , int startPos , int endPos, double[][] def){
this.abc = abc;
this.def = def;
}
#Override
public void run() {
for(int i = startPos ; i < endPos ; i++){
ExecutorService executorService = Executors.newFixedThreadPool(10);
List<Future<double[]>> minDistancePoints = new ArrayList<Future<double[]>>();
for(int j = 0 ; j < def.length ; j = j*100 ){
Future<double[]> minDistancePoint = null;
minDistancePoint = executorService.submit(new ChildThread(abc[i], def, j, j*100));
minDistancePoints.add(minDistancePoint);
}
// How can I wait for all the threads and calculate the MinDistance and
//add it to the actual array
findMinDistanceOfAll(abc[i],minDistancePoints);
executorService.shutdown();
}
}
public void findMinDistanceOfAll(double[] mainPoint, List<Future<double[]>> distancePoints){
// Here I will find the min among the given points and add it actual array.
MinDistanceCalculation.xyz.add(null);
}
}
Child Thread / def threads
public class ChildThread implements Callable<double[]> {
double[] abc = null;
double[][] def = null;
int from;
int to;
public ChildThread(double[] abc, double[][] def, int from, int to) {
this.def = def;
this.abc = abc;
this.from = from;
this.to = to;
}
#Override
public double[] call() throws Exception {
double minDistance = Double.MAX_VALUE;
double currentDistance = 0;
double[] minCandidate = null;
for (int i = from; i < to; i++) {
currentDistance = distance(abc,def[i]);
if (currentDistance < minDistance) {
minDistance = currentDistance;
minCandidate = def[i];
}
}
return minCandidate;
}
public double distance(double[] point1 , double[] point2) {
// Calculates and Returns Euclidean distance
return 0;
}
}
Determine what a parallel task should do. Best parallelization is when there is minimal interaction. So calculating one element of xyz array is best candidate. Splitting def in 10 chunks is bad because that chunks are not independent. Combining 10 elements of abc in one thread may have sense when we want to increase the size of a task and so reduce task's interaction, but this is a not evident optimization and should be done later.
Decide how to run these tasks. Wrapping each task in a separate Runnable and submitting to a thread pool is an universal way but here we can avoid this. Each tack is identified by the index into abc array (and xyz array). We can keep current index in an AtomicInteger and use getAndIncrement to obtain next index.
Since this task is CPU-bound, start N threads where N=number of available processors.
Count the number of finished tasks with CountDownLatch.
Add some initialization and min distance calculation here:
public class MinDistanceCalculation implements Runnable {
AtomicInteger idx=new AtomicInteger();
int inpSize=100;
double[] abc = new double[inpSize];
double[] def = ...
double[] xyz = new double[inpSize];
CountDownLatch counter=new CountDownLatch(inpSize);
public void run() {
for (;;) {
int nextIndex=idx.getAndIncrement();
if (nextIndex>=inpSize) return;
xyz[nextIndex]=minDistance(abc[nextIndex], def);
counter.countDown();
}
void start() {
for (int k=0; k<Runtime.getRuntime.availableProcessors()) {
new Thread(this).start();
}
counter.await();
}
public static void main(String[] a) {
new MinDistanceCalculation().start();
}
}

How to Add Java Multithreading

At work training, I'm writing a Java (in which I have 0 experience) program that should meet the following criteria:
Write a program that replicates distributed computing application
Create central 'scheduler' object which contains a list of M random numbers
Create N processor threads that retrieve a number from the scheduler then loop that many times before requesting another number
If no numbers are available from the scheduler, wait to request another number.
If no more numbers are left, all the threads should end.
So far, I created an object with an array of random numbers, but I really don't know how to proceed with multithreading. Could someone please guide me through it? This is what I have so far, along with comments indicating pseudo code.
public class ThreadDemo extends Thread
{
//create new array of arbitrary size 5
static int SIZE = 5;
static int[] myIntArray = new int[SIZE];
public ThreadDemo()
{
start();
}
class RunnableThread implements Runnable {
Thread runner;
public RunnableThread() {
}
public RunnableThread(String threadName) {
runner = new Thread(this, threadName); // (1) Create a new thread.
System.out.println(runner.getName());
runner.start(); // (2) Start the thread.
}
public void run() {
//Display info about this particular thread
System.out.println(Thread.currentThread());
}
}
public static void main(String[] args)
{
for(int i=0; i<SIZE; i++)
{
myIntArray[i] = (int)(Math.random() * 10);
}
ThreadDemo scheduler = new ThreadDemo();
//create M processor threads that retrieve number from scheduler
//for(int i=0; i<SIZE; i++)
//
//if no threads available
//make the scheduler thread wait() ??
//if empty
//stop() the scheduler thread ??
}
}
Could anyone steer me in the right direction?
Thank you!
As a first pointer: don't start threads in a constructor and don't use the Runnable object to start a thread using itself. It's very confusing to whoever reads the code.
Here's my take on this problem (hope I didn't get carried away):
class Scheduler {
private int[] numbers;
private AtomicInteger current = new AtomicInteger();
public Scheduler(int count) {
Random rand = new Random();
numbers = new int[count];
for(int i = 0; i < count; i++) {
numbers[i] = rand.nextInt();
if(numbers[i] < 0) numbers[i] *= -1;
}
}
public int getNextNumber() {
int local = current.incrementAndGet();
if(local >= numbers.length) {
return -1;
}
return numbers[local];
}
}
First, we define the Scheduler class that holds an array of random (positive) integers and returns a number from the array on-demand, based on an atomically incrementing counter.
class Task implements Runnable {
private Scheduler scheduler;
public Task(Scheduler scheduler) {
this.scheduler = scheduler;
}
public void run() {
while(true) {
int limit = scheduler.getNextNumber(); // get next number
if(limit == -1) return; // no more numbers
System.out.println(limit);
for(int i = 0; i < limit; i++) {
// spin
}
}
}
}
The Task class holds the code that each thread executes. Each thread loops indefinitely requesting numbers from the Scheduler, until the array is exhausted.
public class Test {
public static void main(String[] args) throws InterruptedException {
Scheduler s = new Scheduler(100);
ExecutorService exec = Executors.newFixedThreadPool(4);
for(int i = 0; i < 4; i++) {
exec.submit(new Task(s));
}
exec.shutdown();
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
In the main class we set up a thread pool and execute 4 threads to do the aforementioned tasks.
This is a good place to start. IT will also help to look at a executor service. Here is an example.
You might also want to take a look at some of the concurrent collections. It might be worth using a queue instead of an array so its a little cleaner to tell when something has been pulled out of it.
As per my understanding of your Homework, you need to create a producer and worker thread units. Please refer the below link, which will suits your requirement.
http://www.exampledepot.com/egs/java.lang/WorkQueue.html
Thanks
Thanikachalan
You might want to take a look at te ThreadPoolExecutor
You should end up with something like this.
public static void main(){
ThreadPoolExecutor tpe = new ThreadPoolExecutor(...);
List<Integer> numbers = getNumberList();
for(Integer i : numbers){
tpe.submit(new MyRunnable(i) {
Integer i;
public MyRunnable(Integer i){
this.i=i;
}
#Override
public void run() {
dosomethingWith(i);
}
}
}
}

Categories

Resources