How to access an arraylist after 4 threads are finished - java

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) {
}

Related

I want to print the fibonacci series using two threads. Like 1st number should be printed by 1st thread and then 2nd number by 2nd thread and so on

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.

java multithreading make universal code using list with different size against number of cores

We want to process List exList (which has a variable size) in parallel.
How could we make this to work with different sizes of exList and minimum one core and max 4 cores ?
The given code assumes that exList.size > 40. (if size is < 40 se simply use one thread).
But all of that is hard coded. So - how can this code be enhanced to make parallel runs "dynamically"; dependent on the size of our list?
int threads = Runtime.getRuntime().availableProcessors();
final int start = exList.size() / threads;
try {
Thread t1 = new Thread(new Runnable() {
public void run()
{
for(int i =0; i < start;i++){
System.out.println(exList.get(i));
}
}});
t1.start();
Thread t2 = new Thread(new Runnable() {
public void run()
{
for(int i =start; i < start * 2;i++){
System.out.println(exList.get(i));
}
}});
t2.start();
Thread t3 = new Thread(new Runnable() {
public void run()
{
for(int i = start *2; i < start * 3;i++){
System.out.println(exList.get(i));
}
}});
t3.start();
Thread t4 = new Thread(new Runnable() {
public void run()
{
for(int i =start * 3 ; i < exList.size();i++){
System.out.println(exList.get(i));
}
}});
t4.start();
}catch (Exception e){
}
You are already computing the number of threads that might be good to use.
int threads = Runtime.getRuntime().availableProcessors();
But you are simply drawing the wrong conclusion from that! The idea of computing that start value only adds confusion; it doesn't give you anything meaningful. Instead, simply go for:
int listSize = exList.size();
for (int shardNumber = 0; shardNumber < threads; shardNumber++) {
new Thread(new Runnable() {
public void run() {
for(int listIndex = shardNumber*listSize; listIndex < (shardNumber+1)*listSize; listIndex++) {
System.out.println(exList.get(listIndex));
}
}}).start();
}
In other words: you simply slice your exList into thread "shards". And then you create one thread to process such a shard/slice.
Please note: the above isn't tested. It is meant as idea to get you going! You want to carefully check my math to ensure that the inner loop is really fetching the correct elements!
And hint: avoid creating threads and starting threads on that low level. You better create an ExecutorService and submit runnables. Use abstractions, not "low level" stuff.
exList is a list of strings
final int threads = Runtime.getRuntime().availableProcessors();
final int listSize = exList.size()/threads + 1;
Thread[] t = new Thread[threads];
for (int i = 0; i < threads; i++) {
final int finalshardNumber = i;
final int finalI = i;
t[i] = new Thread() {
public void run() {
for(int listIndex = finalshardNumber * listSize; listIndex < ( finalshardNumber + 1) *listSize; listIndex++) {
try {
//thread // index of exList //string from exList
System.out.println( finalI +" "+ listIndex +" "+ exList.get(listIndex));
}catch (Exception e){
}
}
}}; t[i].start();
}

Java monitors and thread concurrency

I'm trying to build simple multithreading application. But I'm confused about Java monitors. I have many threads that want to format with their data one array. So for example I have Supermarket Threads (data of the thread is in txt file) So first thread have these product (Milk, Cheese, Chocolate) and country code for each product 1,2, 3
SupermarketA
Milk 1
Cheese 2
Chocolate 3
SupermarketB
Yogurt 1
Orangle 2
Bannana 3
Tea 7
Kiwi 9
and I want to format array that has to fields (country_code and count)
So my array should look like that
Country_code count
1 2
2 2
3 2
7 1
9 1
Code
public class SortedArray{
private int num = 0; // num is country code
private int count = 0;
}
So here's my monitor class
public class SingleArray {
private SortedArray[] array;
private int arrayIndex;
private static final int MAX_SIZE = 5;
public SingleArray() {
array = new SortedArray[MAX_SIZE];
arrayIndex = 0;
initArray();
}
private void initArray() {
for (int i = 0; i < MAX_SIZE; i++) {
array[i] = new SortedArray();
}
}
public synchronized void inc(){
awaitUnderMax();
notifyAll();
}
private void awaitUnderMin(){
while (arrayIndex == 0) try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void dec(){
awaitUnderMin();
notifyAll();
}
public void add(ArrayList<Integer> count){
for (int i = 0; i < count.size(); i++) {
singleArray.inc();
int num = count.get(i);
if (singleArray.arrayIndex == 0) { // if array is empty add value to it
singleArray.array[0].num = num;
singleArray.array[0].count++;
singleArray.arrayIndex++;
} else {
if (!isThere(num)) { // if num is a new value to array
singleArray.inc();
int index1 = singleArray.arrayIndex;
if (num > singleArray.array[index1 - 1].num) {
singleArray.inc();
singleArray.array[index1].num = num;
singleArray.inc();
singleArray.array[index1].count++;
singleArray.inc();
singleArray.arrayIndex++;
System.out.println(Thread.currentThread().getName() + " first " + singleArray.array[index1].num);
} else if (num < singleArray.array[index1 - 1].num) { // jei num mazesne uz paskutinia masyvo reiksme
int index = index1 - 1 < 0 ? index1 : index1 - 1;
while (index > 0 && num < singleArray.array[index].num) {
index--;
}
if (index != singleArray.arrayIndex) {
System.out.println(Thread.currentThread().getName() + " sec " + singleArray.array[index].num);
singleArray.array = addPos(singleArray.array, index + 1, num);
}
}
}
}
}
}
public boolean isThere(int number){
for(int i=0; i<singleArray.arrayIndex; i++){
singleArray.inc();
if(number == singleArray.array[i].num){
singleArray.array[i].count++;
return true;
}
}
return false;
}
private void awaitUnderMax(){
while (arrayIndex >= MAX_SIZE) try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void removeValue(int number, int howManyItems){
for(int i=0; i<arrayIndex; i++){
dec();
if(number == array[i].num){
int numberToDelete = array[i].count - howManyItems >= 0 ? howManyItems : array[i].count;
if(array[i].count >= numberToDelete){
array[i].count -= numberToDelete;
}
if(array[i].count == 0){
deleteItem(i);
}
}
if(array[i].count == 0){
deleteItem(i);
}
}
}
Each thread call add(ArrayList<Integer> count) method
So basically what add method does:
Find place where to insert new value (dependng if new value is greater or lower than a previous)
call isThere(int num) method that check if new value is already in array (if so increment count singleArray.array[i].count++) otherwise add new value to array
If array is full arrayIndex == MAX_SIZE wait current thread for other threads to decrement arrayIndex (this is oly one part of code I also have other threads that based on county code decrement array)
So the biggest problem is that multiplethreads need to update single array at the same time (I know that adding synchronized keyword to add method should solve this problem but it only let one thread to run this method at once!) So sometimes all works fine, but sometimes I get really starnge results (for example that country code is 0 (That is imposible!!!) and sometimes new values is placed in wrong array posiitons). Also I think that semaphores should solve this problem, but is it possible to do that with monitors? Thank's for the answers.
EDIT v2
to #Elyasin
public Thread[] setUpShopsBuilderThreads(){
int size = data.getSize();
ArrayList<ArrayList<String>> a = new ArrayList<>();
ArrayList<ArrayList<Integer>> b = new ArrayList<>();
ArrayList<ArrayList<Double>> c = new ArrayList<>();
Thread[] threads = new Thread[size];
for (int i = 0; i < size; i++) {
int tmp = data.getIndex(i);
int range = i + 1 < size ? data.getIndex(i + 1) : data.getWaresSize();
ArrayList<String> name = new ArrayList<>();
ArrayList<Integer> count = new ArrayList<>();
ArrayList<Double> price = new ArrayList<>();
for (int j = tmp; j < range; j++) {
name.add(data.getName(j));
count.add(data.getCount(j));
price.add(data.getPrice(j));
}
a.add(name);
b.add(count);
c.add(price);
}
procesas_1 p1 = new procesas_1(a.get(0), b.get(0), c.get(0));
procesas_2 p2 = new procesas_2(a.get(1), b.get(1), c.get(1));
procesas_3 p3 = new procesas_3(a.get(2), b.get(2), c.get(2));
procesas_4 p4 = new procesas_4(a.get(3), b.get(3), c.get(3));
procesas_5 p5 = new procesas_5(a.get(4), b.get(4), c.get(4));
Thread worker1 = new Thread(p1);
Thread worker2 = new Thread(p2);
Thread worker3 = new Thread(p3);
Thread worker4 = new Thread(p4);
Thread worker5 = new Thread(p5);
threads[0] = worker1;
threads[1] = worker2;
threads[2] = worker3;
threads[3] = worker4;
threads[4] = worker5;
return threads;
}
public static void main(String[] args) {
Starter start = new Starter();
start.read();
start.printShopsData();
start.printUserData();
Thread[] builderThreads = start.setUpShopsBuilderThreads();
for(int i=0; i<builderThreads.length; i++){
builderThreads[i].start();
}
}
what about using the concurrent safe datasets java already provides?
if you want it sorted, this one looks it might work for you:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentSkipListSet.html
just add it as in a normal Collection

how to return value from new Thread by ThreadManager.createThreadForCurrentRequest(new Runnable() gae java

there are 2 part . I am use google app engine java.
1, task Queue, to start 2 process
2, each process using ThreadManager.createThreadForCurrentRequest(new Runnable() {
for 2 Thread
I expect to set the "total_i" value by Thread based on (int i_from, int i_to).
when pass value (1,2) and (3,4) to each Thread, the total of total_i should be 6 and 14.
But the 2 Threads give me the same value 14. I really confused and need help.
Thanks
//part 1 :
total_count = 4; // temp set
record_count= 2;
Queue queue = QueueFactory.getDefaultQueue();
// queue 分段读取 detail data, 每次30个
for (int i = 1; i <= total_count; i += record_count) {
code_from = String.valueOf(i);
code_to = String.valueOf(i + record_count - 1);
queue.add(TaskOptions.Builder.withUrl("/test_DetailDown").method(TaskOptions.Method.GET).param("from", code_from).param("to", code_to));
}
//part 2:
#SuppressWarnings("serial")
public class test_DetailDown extends HttpServlet {
AtomicInteger counter = new AtomicInteger();
final static int ThreadCount = 2;
int[] recordArr = new int[ThreadCount];
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, DeadlineExceededException {
resp.getWriter().println("start");
// this is called by "Queue_Detail_Down" from Queue with parameter : from,
// to
String code_from = req.getParameter("from");
String code_to = req.getParameter("to");
TodayDetail(Integer.valueOf(code_from), Integer.valueOf(code_to));
// process to down data
}
// this is the process to get today datail
private void TodayDetail(int code_from, int code_to) {
int total_i = 0;
// int record_count = 2;
// loop symbol to get detail data from stock.zaobao
for (int i = 0; i < ThreadCount; i++) {
final int i_from = code_from; // pass parameter
final int i_to = code_to;
// thread
Thread thread = ThreadManager.createThreadForCurrentRequest(new Runnable() {
public void run() {
counter.incrementAndGet();
get_detail_data(i_from, i_to); // down web data
counter.decrementAndGet();
}
});
thread.start(); // end thread process
}
// wait all thread
while (true) {
int num = counter.get();
if (num <= 0)
break;
try {
Thread.sleep(300);
} catch (InterruptedException ex) {
}
}
// save data
for (int i = 0; i < ThreadCount; i++) {
total_i = total_i + recordArr[i];
}
System.out.println("after Thread process, total_i =" + total_i);
log("end of program");
}
// core process, get data
private void get_detail_data(int i_from, int i_to) {
for (int i = 0; i < ThreadCount; i++) {
recordArr[i] = i_from + i_to;
}
}
}

Write a program using java threads to print the following sequence 2 3 4 6 6 9 8 12 10 (Multiple of 2 and 3 in a sequence)

Basically what it does is that it prints the following numbers multiple of 2 and 3 in sequence like this
2 3 4 6 6 9 8 12 10 = this is the output
(2*1=2) (3*1=3) (2*2=4) (3*2=6) (2*3=6) (3*3=9) (2*4=8) (3*4=12) (2*5=10) = just a guide
here's my code so far, I'm having trouble displaying it in sequence. I've tried using wait and notify but it's a mess. So far this one is working.
public class Main {
public static void main(String[] args) throws InterruptedException {
final Thread mulof2 = new Thread(){
public void run() {
for (int i = 1; i <= 10; i++) {
int n = 2;
int result = n * i;
System.out.print(result + " ");
}
}
};
Thread mulof3 = new Thread(){
public void run() {
for (int i = 1; i <= 10; i++) {
int n = 3;
int result = n * i;
System.out.print(result + " ");
}
}
};
mulof2.start();
mulof3.start();
}
}
With Java 7 your first choice should be a Phaser. You'll only need one instance of it, created with new Phaser(1). You'll need just two methods for coordination: arrive and awaitAdvance.
Multiplication Table in java using Threads Concept
public class Multiplication extends Thread {
public void run() {
for (int i = 1; i < 10; i++) {
int n = 2;
int result = n * i;
System.out.print(i+"*"+n+"="+result+"\n");
}
}
public static void main(String[] args) throws InterruptedException {
Multiplication mul=new Multiplication();
mul.start();
}
}
Instead of printing during computation, you can aggregate the results into strings and then print both strings in order. After joining with the threads of course.
wait() and notify() are generally too low level, and too complex to use. Try using a more high-level abstraction like Semaphore.
You could have a pair of Semaphore instances: one which allows printing the next multiple of 2, and another one which allows printing the next multiple of 3. Once the next multiple of 2 has been printed, the thread should give a permit to print the next multiple of 3, and vice-versa.
Of course, the initial numbers of permits of the semaphores must be 1 for the multiple-of-2 semaphore, and 0 for the other one.
A simple modification would help you get the required sequence.
You need to declare a semaphore as other have pointed out private Semaphore semaphore;. Then declare another variable to denote which thread has to execute next such as private int threadToExecute; .
Next step is within your thread execute the code between semaphore.acquire(); and semaphore.release();
thread2:
try{
semaphore.acquire();
if(threadToExecute ==2)
semaphore.release();
//write your multiply by 2 code here
threadToExecute = 3;
semaphore.release();
}catch(Exception e){
//exceptions
}
This will nicely synchronize your output.
Below is the code that will give you desired results.
public class Main {
public static void main(String[] args) throws InterruptedException {
final Object lock1 = new Object();
final Object lock2 = new Object();
final Thread mulof2 = new Thread(){
public void run() {
for (int i = 1; i <= 10; i++) {
synchronized (lock1) {
synchronized (lock2) {
lock2.notify();
int n = 2;
int result = n * i;
printResult(result);
}
try {
lock1.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
Thread mulof3 = new Thread(){
public void run() {
for (int i = 1; i <= 10; i++) {
synchronized (lock2) {
synchronized (lock1) {
lock1.notify();
int n = 3;
int result = n * i;
printResult(result);
}
try {
lock2.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
mulof2.start();
mulof3.start();
}
static void printResult(int result)
{
try {
// Sleep a random length of time from 1-2s
System.out.print(result + " ");
Thread.sleep(new Random().nextInt(1000) + 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Categories

Resources