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);
}
}
}
}
Related
I'm new to programming and been studying threads for some time now.
So, the following code should give an output of:
one 98098
two 98099
and it does sometimes.
When I try to run it for a couple of times, it gives different outputs. I can understand that the JVM controls the threads and I can't directly affect it, but some of the outputs are less than 98,000 even though the for loop is adding 1000 for 98 times. How is this happening? Can a thread leave lines behind? Or did I do something wrong (note: the expected output sometimes shows on the screen, but not always)
public class TestThreads {
public static void main(String [] args) {
ThreadOne t1 = new ThreadOne();
Thread one = new Thread(t1);
ThreadTwo t2 = new ThreadTwo();
Thread two = new Thread(t2);
one.start();
two.start();
}
}
class Accum {
private int counter = 0;
private static Accum a = new Accum();
private Accum() {
}
public static Accum getAccum() {
return a;
}
public int getCount() {
return counter;
}
public void updateCounter(int add) {
counter += add;
}
}
class ThreadOne implements Runnable {
Accum a = Accum.getAccum();
public void run() {
for(int x=0; x < 98; x++) {
a.updateCounter(1000);
try {
Thread.sleep(50);
} catch(InterruptedException ex) { }
}
System.out.println("one "+a.getCount());
}
}
class ThreadTwo implements Runnable {
Accum a = Accum.getAccum();
public void run() {
for(int x=0; x < 99; x++) {
a.updateCounter(1);
try {
Thread.sleep(50);
} catch(InterruptedException ex) { }
}
System.out.println("two "+a.getCount());
}
}
Basically, your updateCounter method isn't thread-safe. If it's called from two threads at the same time, you can lose information.
Let's rewrite it to make it more obvious why that's the case:
public void updateCounter(int add) {
// Fetch
int originalValue = counter;
// Compute
int newValue = originalValue + add;
// Store
counter = newValue;
}
Imagine what happens if two threads come into the method at the same time. We'll pretend that there's some "total ordering" of what happens - the reality is more complex than that, but even the simplified form shows the problem. Suppose counter has a value of 5 to start with, and on thread x we're calling updateCounter(3) and on thread y we're calling updateCounter(4). We could imagine this sequence of events:
Thread x executes the "fetch" operation: originalValue = 5 (local variable, unaffected by thread y)
Thread y executes the "fetch" operation: originalValue = 5
Thread x executes the "compute" operation: newValue = 8
Thread y executes the "compute" operation: newValue = 9
Thread x executes the "store" operation: counter = 8 (note that newValue in thread x is separate to the one in thread y)
Thread y executes the "store" operation: counter = 9
So we end up with the value of counter being 9... as if the updateCounter(3) call had never taken place. If the last two operations happened in the reverse order, then counter would be 8 instead.
The way to fix this is to use the AtomicInteger class which is designed specifically to make operations like this atomic:
class Accum {
private final AtomicInteger counter = new AtomicInteger(0);
private static Accum a = new Accum();
private Accum() {
}
public static Accum getAccum() {
return a;
}
public int getCount() {
return counter.get();
}
public void updateCounter(int add) {
counter.addAndGet(add);
}
}
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.
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);
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();
}
}
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.