Reputation: 171
I am trying to create a program, that will give each thread an integer, the thread will then compute a given code with that integer, then return to get another integer. This will continue till all the integers that needed computation have been computed.
As I am not really experienced with multithreading, I am not sure how I can take one thread and change its job, once it finishes with the first task.
Currently this is how I create and execute threads:
public static void main(String[] args){
ComputableInteger a = new ComputableInteger(1);
ComputableInteger b = new ComputableInteger(2);
ComputableInteger c = new ComputableInteger(3);
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
Thread t3 = new Thread(c);
t1.start();
t2.start();
t3.start();
}
Now, this works fine, but it only computes 3 already decided integers. I would like the ability to choose how many integers that they have to compute, and the threads should always just take the first free number in the line. So for example, I do not want to just assign the first 10 integers to t1, the next ten to t2, and so on. Instead I want the first thread finishing, to take the next integer in the line (which would be 4 in this case).
I have been looking a bit on threadPools, but I couldn't make that work either. I hope some of you have some tips!
Edit:
Okay, so I tried to implement the getNext with synchronized on, this is how my run function looks like:
public void run() {
while (Executer.getNext() < 20) {
if(computeInteger(number)) {
Executer.incrementCount();
}
number = Executer.getNext();
}
}
The hope is for it to check every single integer up to 19. It does that, however it manages to skip a few numbers on the way, and seeing I already have synchronized on I am not entirely sure how I fix this.
Edit:
I switched to the ExecuterService to solve this problem, but I have a few problems with how I should execute it properly:
public static void main(String[] args){
final long startTime = System.currentTimeMillis();
executorService.execute(new Runnable() {
public void run() {
int currentNumber;
while ((currentNumber = Executer.getNext()) <= 10000000) {
if(Executer.computeInteger(currentNumber)) {
Executer.incrementCount();
}
}
}
});
The current problem, from what I can see, is that the first thread is the one executing all the code. But how am I going about it if I want to seperate this into one thread taking 1 iteration, while all the other threads operate synchronized?
Upvotes: 1
Views: 67
Reputation: 5440
If you don't want to use Executor service, you can also use the java 8 new stream api :
public static void main(String[] args) {
List<Integer> integerToTreat = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
long start = System.currentTimeMillis();
integerToTreat.parallelStream().forEach(i -> {
// do your work here. For this example, just sleeping 1sec.
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
System.out.println("Finished treating " + integerToTreat.size() + " items in " + (System.currentTimeMillis() - start) + " ms");
}
which will output : Finished treating 8 items in 2068 ms
With this, you can't choose the number of threads or the threadpool. It is using a fixed one shared by all loops using this api, with as many threads in it as you have cores in your cpu.
Upvotes: 1
Reputation: 4430
make a static field that's only accessible through a synchronized getter.
private static int next = 1;
public static synchronized int getNext() {
return next++;
}
In the threads you call this method every time you need a new number!
EDIT: The getNext()
method already increments the counter so you have to call it only once:
public void run() {
while ((number = Executer.getNext()) < 20) {
// Do whatever you have to do with number
// but don't increment the next counter anymore
}
}
Upvotes: 1
Reputation: 1019
Create a fixed size thread pool using ExecutorService class. Put your calculation logic into a runnable class. Iterate over all your integer values in for loop and on each iteration create a runnable object by passing the data on which you want to perform calculation and submit it to ExecutorService thread pool.
Upvotes: 4