I want fibonacci series to be printed by threads and the 1st number of the series should be printed by 1st thread then 2nd number by 2nd thread then 3rd by 1st thread and 4th by 2nd and so on.
I tried this code by using arrays like printing the array elements using thread but I am not able to switch between the threads.
class Fibonacci{
void printFibonacci() {
int fibArray[] = new int[10];
int a = 0;
int b = 1;
fibArray[0] = a;
fibArray[1] = b;
int c;
for(int i=2;i<10;i++) {
c = a+b;
fibArray[i] = c;
a = b;
b = c;
}
for(int i=0;i<10;i++) {
if(Integer.parseInt(Thread.currentThread().getName())%2==0 && (i%2==0))
{
System.out.println("Thread " +Thread.currentThread().getName()+" "+fibArray[i]);
try{
wait();
}catch(Exception e) {}
}
else if(Integer.parseInt(Thread.currentThread().getName())%2!=0 && (i%2!=0))
{
System.out.println("Thread " +Thread.currentThread().getName()+" "+fibArray[i]);
}
}
}
}
public class FibonacciUsingThread {
public static void main(String[] args) throws Exception {
Fibonacci f = new Fibonacci();
Thread t1 = new Thread(()->
{
f.printFibonacci();
});
Thread t2 = new Thread(()->
{
f.printFibonacci();
});
t1.setName("0");
t2.setName("1");
t1.start();
t1.join();
t2.start();
}
}
The following line in your code is causing t1 to finish before t2 can start.
t1.join();
Apart from this, you need to synchronize on the method, printFibonacci.
You can do it as follows:
class Fibonacci {
synchronized void printFibonacci() throws InterruptedException {
int fibArray[] = new int[10];
int a = 0;
int b = 1;
fibArray[0] = a;
fibArray[1] = b;
int c;
for (int i = 2; i < 10; i++) {
c = a + b;
fibArray[i] = c;
a = b;
b = c;
}
for (int i = 0; i < 10; i++) {
String currentThreadName = Thread.currentThread().getName();
if (currentThreadName.equals("1")) {
if (i % 2 == 0) {
System.out.println("Thread " + Thread.currentThread().getName() + " " + fibArray[i]);
notify();
} else {
wait();
}
} else if (currentThreadName.equals("0")) {
if (i % 2 == 1) {
System.out.println("Thread " + Thread.currentThread().getName() + " " + fibArray[i]);
notify();
} else {
wait();
}
}
}
}
}
public class Main {
public static void main(String[] args) {
Fibonacci f = new Fibonacci();
Thread t1 = new Thread(() -> {
try {
f.printFibonacci();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
f.printFibonacci();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.setName("0");
t2.setName("1");
t1.start();
t2.start();
}
}
Output:
Thread 1 0
Thread 0 1
Thread 1 1
Thread 0 2
Thread 1 3
Thread 0 5
Thread 1 8
Thread 0 13
Thread 1 21
Thread 0 34
Apart from all being said and already answered, I would just like to add one alternative approach to Fibonacci sequence implemetation, without arrays and in-advance dimensioning:
public class Fibonacci {
private int index = -1;
private int previous = 0;
private int last = 1;
synchronized public int getNext() {
index++;
if( index == 0 ) return previous;
if( index == 1 ) return last;
int next = last + previous;
if( next < 0 ) throw new ArithmeticException( "integer overflow" );
previous = last;
last = next;
return next;
}
}
Limited only by overflow of numeric data type, in this case integer.
As "#Live and Let Live" pointed out, correctness-wise the main issues with your code is the missing synchronized clause and calling join of the first thread before starting the second thread.
IMO you could clean the code a bit by first separating a bite the concerns, namely, the class Fibonacci would only responsible for calculation the Fibonacci of a given array:
class Fibonacci{
void getFibonacci(int[] fibArray) {
int a = 0;
int b = 1;
fibArray[0] = a;
fibArray[1] = b;
int c;
for(int i=2;i<fibArray.length;i++) {
c = a+b;
fibArray[i] = c;
a = b;
b = c;
}
}
}
In this way, you keep your Fibonacci class concise without any thread-related code. Moreover, the getFibonacci is now more abstract; you can calculate the fib of more than just 10 elements like you had before.
Then on the class FibonacciUsingThread:
public class FibonacciUsingThread {
public static void main(String[] args) throws Exception {
int [] array_fib = new int[10];
Fibonacci f = new Fibonacci();
f.getFibonacci(array_fib);
Thread t1 = new Thread(()->
{
for(int i = 0; i < array_fib.length; i+=2)
System.out.println("Thread 1:" + array_fib[i]);
});
Thread t2 = new Thread(()->
{
for(int i = 1; i < array_fib.length; i+=2)
System.out.println("Thread 2:" + array_fib[i]);
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
First, you calculate the Fibonaccis using the main thread, there is no point in having all the threads calculate the same thing. Afterward, you specified that Thread 1 and Thread 2 will print the even and odd positions, respectively.
Unless this is just an exercise to play around with threads and synchronization there is not much sense in using threads to do this kind of work. In your code, the part worth parallelizing is the calculation of the Fibonacci numbers themselves, not the printing part.
The code previously shown will not print the Fibonacci numbers in order, for that you need to ensure that the threads wait for one another after iterating through each element of the array. Hence, you need to adapt the code that will be executed by the threads, namely:
Thread t1 = new Thread(()->
{
synchronized (array_fib){
for(int i = 0; i < array_fib.length; i++)
if(i % 2 == 0) {
System.out.println("Thread 1:" + array_fib[i]);
try {
array_fib.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
array_fib.notify();
}
});
Thread t2 = new Thread(()->
{
synchronized (array_fib){
for(int i = 0; i < array_fib.length; i++)
if(i % 2 != 0) {
System.out.println("Thread 2:" + array_fib[i]);
try {
array_fib.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
array_fib.notify();
}
});
We can remove the code redundancy by extracting a method with the work that will be assigned to the Threads. For instance:
private static void printFib(String threadName, int[] array_fib, Predicate<Integer> predicate) {
for (int i = 0; i < array_fib.length; i++)
if (predicate.test(i)) {
System.out.println(threadName + " : " + array_fib[i]);
try {
array_fib.wait();
} catch (InterruptedException e) {
// do something about it
}
} else
array_fib.notify();
}
and the main code:
public static void main(String[] args) throws Exception{
int [] array_fib = new int[10];
Fibonacci f = new Fibonacci();
f.getFibonacci(array_fib);
Thread t1 = new Thread(()-> {
synchronized (array_fib){
printFib("Thread 1:", array_fib, i1 -> i1 % 2 == 0);
}
});
Thread t2 = new Thread(()-> {
synchronized (array_fib){
printFib("Thread 2:", array_fib, i1 -> i1 % 2 != 0);
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
As an alternative, you can use a fair Semaphore to alternate between threads, and an AtomicReference to keep the shared status. Here's an example:
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicReference;
public class FibonacciConcurrent {
public static void main(String[] args) throws InterruptedException {
// needs to be fair to alternate between threads
Semaphore semaphore = new Semaphore(1, true);
// set previous to 1 so that 2nd fibonacci number is correctly calculated to be 0+1=1
Status initialStatus = new Status(1, 0, 1);
AtomicReference<Status> statusRef = new AtomicReference<>(initialStatus);
Fibonacci fibonacci = new Fibonacci(20, semaphore, statusRef);
Thread thread1 = new Thread(fibonacci);
Thread thread2 = new Thread(fibonacci);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
}
private static final class Status {
private final long previous;
private final long current;
private final int currentIndex;
private Status(long previous, long current, int currentIndex) {
this.previous = previous;
this.current = current;
this.currentIndex = currentIndex;
}
}
private static final class Fibonacci implements Runnable {
private final int target;
private final Semaphore semaphore;
private final AtomicReference<Status> statusRef;
private Fibonacci(int target, Semaphore semaphore, AtomicReference<Status> statusRef) {
this.target = target;
this.semaphore = semaphore;
this.statusRef = statusRef;
}
#Override
public void run() {
try {
process();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted", e);
}
}
private void process() throws InterruptedException {
while (!Thread.currentThread().isInterrupted()) {
try {
semaphore.acquire();
Status status = statusRef.get();
String threadName = Thread.currentThread().getName();
if (status.currentIndex > target) return;
System.out.println(
threadName + ": fibonacci number #" + status.currentIndex + " - " + status.current);
long next = status.previous + status.current;
Status newStatus = new Status(status.current, next, status.currentIndex + 1);
statusRef.set(newStatus);
} finally {
semaphore.release();
}
}
}
}
}
Will print:
Thread-0: fibonacci number #1 - 0
Thread-1: fibonacci number #2 - 1
Thread-0: fibonacci number #3 - 1
Thread-1: fibonacci number #4 - 2
Thread-0: fibonacci number #5 - 3
Note that this solution does not only print on the threads - it does the actual calculation on the threads as well - e.g. when it's Thread A's turn, it uses the previous status that was calculated by Thread B to calculate the next fibonacci number.
I am trying to find a way to generate inner loops on demand (and have the depth as a variable).
In the following example, I am trying to generate a list of references such as jobo.2.2.2.2.2.2 where each .2 is added in the inner loop.
Here is what I have at the moment when I implement the new loop manually for 5 level of depth (i, j, k, l):
public void buildTaskList(){
String jobName ="jobo";
String last="";
long max=3;
List<String> tasks = new ArrayList<>();
for (long i = 1; i <= max; i++) {
for (long j = 1; j <= max; j++) {
if (j==max){
last="*";
tasks.add(jobName+"."+i+"."+j+last);
}else {
last="";
for (long k = 1; k <= max; k++) {
if (k==max){
last="*";
tasks.add(jobName+"."+i+"."+j+"."+k+last);
}else {
last="";
for (long l = 1; l <= max; l++) {
if (l==max){
last="*";
tasks.add(jobName+"."+i+"."+j+"."+k+"."+l+last);
}else{
last="";
for (long m = 1; m <= max; m++) {
if (m==max){
last="*";
tasks.add(jobName+"."+i+"."+j+"."+k+"."+l+"."+m+last);
}else{
last="";
for (long n = 1; n <= max; n++) {
if (n==max)last="*";else last="";
tasks.add(jobName+"."+i+"."+j+"."+k+"."+l+"."+m+"."+n+last);
}
}
}
}
}
}
}
}
}
}
tasks.add(jobName+"."+(max+1)+last);
System.out.println(tasks);
}
The result here is:
jobo.1.1.1.1.1.1, jobo.1.1.1.1.1.2, jobo.1.1.1.1.1.3*, jobo.1.1.1.1.2.1, jobo.1.1.1.1.2.2, jobo.1.1.1.1.2.3*, jobo.1.1.1.1.3*, jobo.1.1.1.2.1.1, jobo.1.1.1.2.1.2, jobo.1.1.1.2.1.3*, jobo.1.1.1.2.2.1, jobo.1.1.1.2.2.2, jobo.1.1.1.2.2.3*, jobo.1.1.1.2.3*, jobo.1.1.1.3*, jobo.1.1.2.1.1.1, jobo.1.1.2.1.1.2, jobo.1.1.2.1.1.3*, jobo.1.1.2.1.2.1, jobo.1.1.2.1.2.2, jobo.1.1.2.1.2.3*, jobo.1.1.2.1.3*, jobo.1.1.2.2.1.1, jobo.1.1.2.2.1.2, jobo.1.1.2.2.1.3*, jobo.1.1.2.2.2.1, jobo.1.1.2.2.2.2, jobo.1.1.2.2.2.3*, jobo.1.1.2.2.3*, jobo.1.1.2.3*, jobo.1.1.3*, jobo.1.2.1.1.1.1, jobo.1.2.1.1.1.2, jobo.1.2.1.1.1.3*, jobo.1.2.1.1.2.1, jobo.1.2.1.1.2.2, jobo.1.2.1.1.2.3*, jobo.1.2.1.1.3*, jobo.1.2.1.2.1.1, jobo.1.2.1.2.1.2, jobo.1.2.1.2.1.3*, jobo.1.2.1.2.2.1, jobo.1.2.1.2.2.2, jobo.1.2.1.2.2.3*, jobo.1.2.1.2.3*, jobo.1.2.1.3*, jobo.1.2.2.1.1.1, jobo.1.2.2.1.1.2, jobo.1.2.2.1.1.3*, jobo.1.2.2.1.2.1, jobo.1.2.2.1.2.2, jobo.1.2.2.1.2.3*, jobo.1.2.2.1.3*, jobo.1.2.2.2.1.1, jobo.1.2.2.2.1.2, jobo.1.2.2.2.1.3*, jobo.1.2.2.2.2.1, jobo.1.2.2.2.2.2, jobo.1.2.2.2.2.3*, jobo.1.2.2.2.3*, jobo.1.2.2.3*, jobo.1.2.3*, jobo.1.3*, jobo.2.1.1.1.1.1, jobo.2.1.1.1.1.2, jobo.2.1.1.1.1.3*, jobo.2.1.1.1.2.1, jobo.2.1.1.1.2.2, jobo.2.1.1.1.2.3*, jobo.2.1.1.1.3*, jobo.2.1.1.2.1.1, jobo.2.1.1.2.1.2, jobo.2.1.1.2.1.3*, jobo.2.1.1.2.2.1, jobo.2.1.1.2.2.2, jobo.2.1.1.2.2.3*, jobo.2.1.1.2.3*, jobo.2.1.1.3*, jobo.2.1.2.1.1.1, jobo.2.1.2.1.1.2, jobo.2.1.2.1.1.3*, jobo.2.1.2.1.2.1, jobo.2.1.2.1.2.2, jobo.2.1.2.1.2.3*, jobo.2.1.2.1.3*, jobo.2.1.2.2.1.1, jobo.2.1.2.2.1.2, jobo.2.1.2.2.1.3*, jobo.2.1.2.2.2.1, jobo.2.1.2.2.2.2, jobo.2.1.2.2.2.3*, jobo.2.1.2.2.3*, jobo.2.1.2.3*, jobo.2.1.3*, jobo.2.2.1.1.1.1, jobo.2.2.1.1.1.2, jobo.2.2.1.1.1.3*, jobo.2.2.1.1.2.1, jobo.2.2.1.1.2.2, jobo.2.2.1.1.2.3*, jobo.2.2.1.1.3*, jobo.2.2.1.2.1.1, jobo.2.2.1.2.1.2, jobo.2.2.1.2.1.3*, jobo.2.2.1.2.2.1, jobo.2.2.1.2.2.2, jobo.2.2.1.2.2.3*, jobo.2.2.1.2.3*, jobo.2.2.1.3*, jobo.2.2.2.1.1.1, jobo.2.2.2.1.1.2, jobo.2.2.2.1.1.3*, jobo.2.2.2.1.2.1, jobo.2.2.2.1.2.2, jobo.2.2.2.1.2.3*, jobo.2.2.2.1.3*, jobo.2.2.2.2.1.1, jobo.2.2.2.2.1.2, jobo.2.2.2.2.1.3*, jobo.2.2.2.2.2.1, jobo.2.2.2.2.2.2, jobo.2.2.2.2.2.3*, jobo.2.2.2.2.3*, jobo.2.2.2.3*, jobo.2.2.3*, jobo.2.3*, jobo.3.1.1.1.1.1, jobo.3.1.1.1.1.2, jobo.3.1.1.1.1.3*, jobo.3.1.1.1.2.1, jobo.3.1.1.1.2.2, jobo.3.1.1.1.2.3*, jobo.3.1.1.1.3*, jobo.3.1.1.2.1.1, jobo.3.1.1.2.1.2, jobo.3.1.1.2.1.3*, jobo.3.1.1.2.2.1, jobo.3.1.1.2.2.2, jobo.3.1.1.2.2.3*, jobo.3.1.1.2.3*, jobo.3.1.1.3*, jobo.3.1.2.1.1.1, jobo.3.1.2.1.1.2, jobo.3.1.2.1.1.3*, jobo.3.1.2.1.2.1, jobo.3.1.2.1.2.2, jobo.3.1.2.1.2.3*, jobo.3.1.2.1.3*, jobo.3.1.2.2.1.1, jobo.3.1.2.2.1.2, jobo.3.1.2.2.1.3*, jobo.3.1.2.2.2.1, jobo.3.1.2.2.2.2, jobo.3.1.2.2.2.3*, jobo.3.1.2.2.3*, jobo.3.1.2.3*, jobo.3.1.3*, jobo.3.2.1.1.1.1, jobo.3.2.1.1.1.2, jobo.3.2.1.1.1.3*, jobo.3.2.1.1.2.1, jobo.3.2.1.1.2.2, jobo.3.2.1.1.2.3*, jobo.3.2.1.1.3*, jobo.3.2.1.2.1.1, jobo.3.2.1.2.1.2, jobo.3.2.1.2.1.3*, jobo.3.2.1.2.2.1, jobo.3.2.1.2.2.2, jobo.3.2.1.2.2.3*, jobo.3.2.1.2.3*, jobo.3.2.1.3*, jobo.3.2.2.1.1.1, jobo.3.2.2.1.1.2, jobo.3.2.2.1.1.3*, jobo.3.2.2.1.2.1, jobo.3.2.2.1.2.2, jobo.3.2.2.1.2.3*, jobo.3.2.2.1.3*, jobo.3.2.2.2.1.1, jobo.3.2.2.2.1.2, jobo.3.2.2.2.1.3*, jobo.3.2.2.2.2.1, jobo.3.2.2.2.2.2, jobo.3.2.2.2.2.3*, jobo.3.2.2.2.3*, jobo.3.2.2.3*, jobo.3.2.3*, jobo.3.3*, jobo.4*
Anyone knows how this can be simplified and controlled by a variable int depth=123; for example?
Thanks
This option avoids recursion, and simply counts as you would when deciding the next element in the sequence:
private static class LevelGenerator implements Iterator<String> {
private int[] current; // min,min,min => min,min,min+1 => ... max,max,max
private int min, max; // at each position in current[] array
private String next; // to be returned when next() is called
public LevelGenerator(int levels, int min, int max) {
this.current = new int[levels];
for (int i=0; i<levels; i++) this.current[i] = min;
this.next = output();
this.min = min;
this.max = max;
}
/**
* Int array to string
*/
private String output() {
StringBuilder sb = new StringBuilder();
for (int i : current) sb.append("." + i);
return sb.toString();
}
/**
* Updates current and next
* counts as a human would: increments the last index that is not yet `max`,
* and then places all elements after it to `min`
*/
private String step() {
for (int i=current.length-1; i>=0; i--) {
if (current[i] < max) {
current[i] ++;
for (int j=i+1; j<current.length; j++) {
current[j] = min;
}
return output(); // next step is ready
}
}
return null; // no next step
}
#Override
public String next() {
if (next == null) throw new IllegalStateException("iteration is finished");
String output = next;
next = step();
return output;
}
#Override
public boolean hasNext() {
return next != null;
}
}
public static void main(String ... args) {
LevelGenerator l = new LevelGenerator(3, 1, 4);
while (l.hasNext()) {
System.out.println("job" + l.next());
}
}
The output for this example would be:
job.1.1.1
job.1.1.2
job.1.1.3
job.1.1.4
job.1.2.1
job.1.2.2
job.1.2.3
job.1.2.4
job.1.3.1
job.1.3.2
job.1.3.3
job.1.3.4
job.1.4.1
job.1.4.2
job.1.4.3
job.1.4.4
job.2.1.1
...
job.4.4.4
You can use Recursion (see wiki https://en.wikipedia.org/wiki/Recursion_(computer_science))
for example (draft, not checking)
#Test
public void buildTaskList1() {
String jobName ="job";
int depth=5;
int max=3;
List<String> tasks = new ArrayList<>();
for (long i = 1; i <= max; i++) {
buildTaskListRecursion(max, depth, tasks, jobName + "."+i);
}
tasks.add(jobName+"."+(max+1)+"*");
}
public void buildTaskListRecursion(int max,int depth, List<String> tasks, String jobName){
String last="";
for (long j = 1; j <= max; j++) {
if (j==max){
last="*";
tasks.add(jobName+"."+j+last);
}else {
depth--;
if(depth > 0) {
buildTaskListRecursion(max, depth, tasks, jobName+"."+j);
} else {
tasks.add(jobName+"."+j);
}
}
}
}
Yes
1. Support indexes
Create a stack of indexes of the size of depth.
2. Handle the levels properly
You need a currentDepth index to know where you were. This is 0 at first. Whenever an item is increased, push a new item to the stack with 0 as index. Whenever an item is going beyond max, pop it from the stack and increment the previous element. When the first element is popped, you completed all the work
3. You will need to logically know where you were.
Alternatively you could generate code
But that's much more complicated.
EDIT
In agreement with Bdzzaid's legitimate request, I will briefly talk about the Composite Design Pattern. First, let's see a diagram from the page he shared with us:
Source: https://dzone.com/articles/composite-design-pattern-in-java-1
That's a good read I can wholeheartedly recommend to future readers. The idea is that we use the composition of very similar components in a tree-like manner. The pattern is applied on a stack in our case, which can be thought about as a tree having a single branch in all cases. The reason this is beneficial to think about in this way is that we might want to add support for multiple loops, maybe even in an assymmetryc manner at some point. Now, the components are the levels/indexes in our case and they, together form a composition of the stack (or, in more general terms, the tree).
This pattern can be reused in many different situations, so it is advisable to get familiar with it if you not already have.
Currently when I run the program, the threads are running at random. For example the current output is :
Global.sharedBuffer[0] = 2
Global.sharedBuffer[1] = 1
Global.sharedBuffer[2] = 1
Global.sharedBuffer[3] = 1
Global.sharedBuffer[4] = 1
Global.sharedBuffer[5] = 1
Global.sharedBuffer[6] = 1
Global.sharedBuffer[7] = 1
Global.sharedBuffer[8] = 1
Global.sharedBuffer[9] = 1
Global.sharedBuffer[10] = 2
Global.sharedBuffer[11] = 4
Global.sharedBuffer[12] = 3
What I want is from sharedBuffer 0 to 9 all 1's , then from 10 - 19 all 2's and etc. I added a synchronization block thinking it would do this, however, it just stopped it from context switching every time a thread was called. How do you go about implementing this?
CODE:
import java.io.*;
import java.lang.*;
import java.util.*;
class MyThreadExample2 {
public static void main(String[] args) {
HelloThread ht1 = new HelloThread(1);
HelloThread ht2 = new HelloThread(2);
HelloThread ht3 = new HelloThread(3);
HelloThread ht4 = new HelloThread(4);
ht1.start();
ht2.start();
ht3.start();
ht4.start();
}
}
class Global {
public static int[] sharedBuffer = new int[1000];
public static int in = 0;
}
class HelloThread extends Thread {
int threadID;
HelloThread(int threadID) {
System.out.println("threadID: " + threadID);
this.threadID = threadID;
}
public synchronized void run() {
for (int i = 0; i < 100; i++) {
if((Global.in >= 0 || Global.in <= 99) && (this.threadID == 1))
Global.sharedBuffer[Global.in] = this.threadID;
else if((Global.in >= 100 || Global.in <= 199) && (this.threadID == 2))
Global.sharedBuffer[Global.in] = this.threadID;
else if((Global.in >= 200 || Global.in <= 299) && (this.threadID == 3))
Global.sharedBuffer[Global.in] = this.threadID;
else if((Global.in >= 300 || Global.in <= 399) && (this.threadID == 4))
Global.sharedBuffer[Global.in] = this.threadID;
System.out.println("Thread " + this.threadID + " has written "
+ this.threadID + " to Global.sharedBuffer[" + Global.in + "]\n");
Global.in++;
}
if (this.threadID == 4)
{
try {this.sleep(2000L);
}
catch (Throwable e) {e.printStackTrace();
}
System.out.println("The final buffer is **************\n");
for (int i = 0; i < 30; i++) {
System.out.println("Global.sharedBuffer[" + i + "] = " +
Global.sharedBuffer[i]);
} // for
} // if
} // run
} // end Thread
Multi-threading only works if you can formulate tasks which can be performed independently of others. You have to avoid shared variables and if you can’t avoid it, the access must be properly guarded, which usually implies limiting the concurrency of the thread execution.
For your task it is simple to formulate independent tasks as each thread shall write into a different region of the array:
public class ThreadingExample {
public static void main(String[] args) {
final int numThread=4, chunkSize=10;
int[] array=new int[numThread*chunkSize];
Thread[] thread=new Thread[numThread];
// create threads and define their jobs
for(int t=0, p=0; t<numThread; t++, p+=chunkSize) {
thread[t]=new Thread(new FillInJob(array, t, p, chunkSize));
}
// start the threads
for(Thread t: thread) t.start();
// now all running concurrently
// wait for completion
try {
for(Thread t: thread) t.join();
} catch(InterruptedException ex) {
throw new AssertionError(ex);
}
// use result
System.out.println(java.util.Arrays.toString(array));
}
}
class FillInJob implements Runnable {
private final int[] targetArray;
private final int myID, startIndex, endIndex;
FillInJob(int[] target, int id, int start, int size) {
targetArray=target;
myID=id;
startIndex=start;
endIndex=start+size;
}
public void run() {
for(int ix=startIndex; ix<endIndex; ix++)
targetArray[ix]=myID;
}
}
i got 4 threads running and ech run increases the size of a global arraylist.But i cant access the resulting arraylist after the threads are finished. Is there a way to get access to the resulting arraylist..or how does it work with threads and resutling datastructures??
List<MyObject> head = a.subList(0, 2000);
List<MyObject> body = a.subList(2001, 5000);
List<MyObject> body2 = a.subList(5001, 8000);
List<MyObject> tail = a.subList(8001, a.size());
//System.out.println(tail.size());
createAndRunFirst(head);
createAndRunFirst(body);
these are the calls
and this is the method which is called 4 times..and i need the currCDO arrylist
public void algo(List<MyObject>list){
MyObject a = null;
MyObject b = null;
int e=0;
String curr1="";
String curr2="";
for (int i = 0; i < list.size(); i++) {
a =list.get(i);
curr1= a.getStreetName();
if(curr1.contains("-")){
curr1=curr1.replace("-", " ");
}
if(curr1.contains("STRASSE")){
curr1=curr1.replace("STRASSE", "STR.");
}
else{
curr1=a.getStreetName();
}
for (int j = 0; j < lotse.size(); j++) {
b = lotse.get(j);
curr2=b.getStreetName();
if(curr2.contains("-")){
curr2=curr2.replace("-", " ");
}
if(curr2.contains("STRASSE")){
curr2=curr2.replace("STRASSE", "STR.");
}
else{
curr2=b.getStreetName();
}
int d = dL.execute(curr1,curr2);
if(curr1.length()==curr2.length()){
e=0;
}
if(curr1.length()< curr2.length()){
e=(curr2.length()*30)/100;
//System.out.println(d);
}
if(curr1.length()> curr2.length()){
e=(curr1.length()*30)/100;
//System.out.println(d);
}
if(d<e && a.getPcode().contains(b.getPcode())){
int x=a.getInstituteName().length();
int y=b.getInstituteName().length();
if(x<y){
currCDO.add(a);
}
if(y<x){
currCDO.add(a);
if(x==y){
currCDO.add(a);
}
break;}else{
//System.out.println(a.getInstituteName()+"******");
restCDO.add(a);
}
}//System.out.println(currCDO.size() +"*****");
}
}
}
public void createAndRunFirst(final List<CrawlerDataObject> list) {
Thread thread = new Thread(new Runnable() {
#Override
public void run(){
algo(list);
}
});
thread.start();
}
Assuming currCDO is global, are you waiting for all the threads to finish?
You might want to consider building an output list for each thread and then concactenating them at the end. This would avoid locking. You could use a threadsafe list too, but that might be slower. I don't know c# specifically, but I assume there are threadsafe lists.
int i0 = 0;
int c = a.size()/cThread;
new List<MyObject>()[cThread];
for (int iThread=0 ; iThread<cThread ; ++iThread, i0+=c) {
createAndRunFirst(a.subList(i0, i0 + c - 1), aOut[iThread]);
}
waitForAllThreads(); // i don't know the c# for this
for (int iThread=0 ; iThread<cThread ; ++iThread) {
currCDO += aOut[iThread];
}
public void createAndRunFirst(final List<CrawlerDataObject> list, List<CrawlerDataObject> out) {
Thread thread = new Thread(new Runnable() {
#Override
public void run(){
algo(list, out);
}
});
public void algo(List<MyObject> list, List<MyObject> currCDO) {
}