How to deal with multiple threads with multiple scanners (multiple resources)? - java

I'm trying to get data from four different sources with four scanners. I do realize that I need to use threads. But here's the error message:
P.S = paths for the files were fine before using thread. ( I was using one file, path was ok.)
null
null
null
null
java.lang.ArrayIndexOutOfBoundsException: 41705
at getText.getCities(getText.java:132)
at getText$1.run(getText.java:23)
at java.lang.Thread.run(Unknown Source)
java.lang.ArrayIndexOutOfBoundsException: 41705
at getText.getNames(getText.java:112)
at getText$2.run(getText.java:30)
at java.lang.Thread.run(Unknown Source)
Code Itself
public class getText {
static int ln = 41705;
static String [] icaos = new String[ln];
static String [] iatas = new String[ln];
static String [] names = new String[ln];
static String [] cities = new String[ln];
public final Runnable typeA;
public final Runnable typeB;
public final Runnable typeC;
public final Runnable typeD;
public getText() {
typeA = new Runnable() {
public void run() {
getText.this.getCities();
}
};
typeB = new Runnable() {
public void run() {
getText.this.getNames();
}
};
typeC = new Runnable() {
public void run() {
getText.this.getIcao();
}
};
typeD = new Runnable() {
public void run() {
getText.this.getIata();
}
};
}
public static void main(String[] args) {
// TODO Auto-generated method stub
getText x = new getText();
new Thread(x.typeA).start();
new Thread(x.typeB).start();
new Thread(x.typeC).start();
new Thread(x.typeD).start();
System.out.println(icaos[32541]);
System.out.println(iatas[32541]);
System.out.println(names[32541]);
System.out.println(cities[32541]);
}
public void getIcao () {
try {
int i=0;
InputStream icao_stream = new FileInputStream("src/icao.txt");
Scanner icao_s = new Scanner(icao_stream);
icao_s.useDelimiter(",");
while(icao_s.hasNext()) {
icaos[i] = icao_s.next();
i++;
}
icao_s.close();
icao_stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void getIata() {
try {
int i=0;
InputStream iata_stream = new FileInputStream("src/iata.txt");
Scanner iata_s = new Scanner(iata_stream);
iata_s.useDelimiter(",");
while(iata_s.hasNext()) {
iatas[i] = iata_s.next();
i++;
}
iata_s.close();
iata_stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void getNames() {
try {
int i=0;
InputStream names_stream = new FileInputStream("src/names.txt");
Scanner names_s = new Scanner(names_stream);
names_s.useDelimiter(",");
while(names_s.hasNext()) {
names[i] = names_s.next();
i++;
}
names_s.close();
names_stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void getCities() {
try {
int i=0;
InputStream cities_stream = new FileInputStream("src/cities.txt");
Scanner cities_s = new Scanner(cities_stream);
cities_s.useDelimiter(",");
while(cities_s.hasNext()) {
cities[i] = cities_s.next();
i++;
}
cities_s.close();
cities_stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

So the problem now is you have started your threads, but the control returns immediately to the main thread and your other threads are not finished working by then. What you need is to wait for those threads to finish working and then check for results. There are multiple ways to achieve that. A simple one is to change your main to:
public static void main(String[] args) {
getText x = new getText();
List<Thread> threads = new ArrayList<>();
threads.add(new Thread(x.typeA));
threads.add(new Thread(x.typeB));
threads.add(new Thread(x.typeC));
threads.add(new Thread(x.typeD));
threads.forEach(t -> t.start());
threads.forEach(t -> {
try {
//this makes the main thread to wait for thread "t" to finish
t.join();
} catch (InterruptedException e) {
// log or throw or anything you need to do
}
});
System.out.println(icaos[32541]);
System.out.println(iatas[32541]);
System.out.println(names[32541]);
System.out.println(cities[32541]);
}
This is not the most optimal solution but the simplest one. Others better options would be to use a CyclicBarrier or ExecutorService among others.

Related

Java - suspend thread until other thread event

I have an object A on which I'm updating some data every second and other objects B and C which want to use the data only once per update.
Every object work in parallel.
How can I make B and C wait for the update in A ?
I've seen some similar questions but their responses didn't help me.
I've seen that I could use a "synchronized" bloc on an object D, but they just put the bloc without telling how to instanciate or share that object.
The following code is what I use for my tests. I managed to get them working in parallel but I'm stuck with the suspending part.
This is the class for A
public class Master{
public static void main(String[] args) throws Exception {
Worker B = new Worker("B");
B.start();
Worker C = new Worker("C");
C.start();
while(true)
{
Thread.sleep(1000);
// update data
// notify every thread waiting that they can resume
}
}
}
This is the class used for B and C
public class Worker extends Thread
{
Worker(String name)
{
super("Worker " + name);
}
public void run()
{
int i = 0;
while(!this.isInterrupted())
{
// wait for A to update data
System.out.println(i);
i++;
}
System.out.println("thread interrupted");
}
}
From there, what do I need to add for the purpose I'm looking for ?
To do it very low level, only using the lang APIs, you should use wait/notifyAll.
Not that I used Main.class as an arbitrary object to synchronize
public class Main {
public static void main(String[] args) {
SharedData sharedData = new SharedData();
Worker w1 = new Worker("Worker 1", sharedData);
Worker w2 = new Worker("Worker 2", sharedData);
w1.start();
w2.start();
while (true) {
try {
Thread.sleep(1000);
sharedData.increase();;
System.out.println("Master: " + sharedData.value());
synchronized (Main.class) {
Main.class.notifyAll();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class SharedData {
private int data = 0;
public void increase () {
data++;
}
public int value() {
return data;
}
}
class Worker extends Thread {
private String workerName;
private SharedData sharedData;
public Worker(String workerName, SharedData sharedData) {
super();
this.workerName = workerName;
this.sharedData = sharedData;
}
#Override
public void run() {
while (true) {
try {
synchronized (Main.class) {
Main.class.wait();
}
System.out.println(workerName + ": " + sharedData.value());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Not sure if I understand you correctly, but this might be worth checking out for you:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html
Why use threads at all? Why not just do this?
public class Master {
public static void main(String[] args) {
Worker B = new Worker("B");
Worker C = new Worker("C");
while(true) {
Thread.sleep(1000);
updateData();
B.doWork();
C.doWork();
}
}
}
public class Worker
{
public void doWork() {
System.out.println(i);
i++;
}
private int i = 0;
}

Using threading to get tweets using Streaming API without getting rate-limited

I want to use threading to stream the tweets but I am getting rate-limited. What am I doing wrong?
public class AppThread {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
Runnable worker = new App("Thread" + i);
executor.execute(worker);//calling execute method of ExecutorService
}
executor.shutdown();
while (!executor.isTerminated()) { }
System.out.println("Finished all threads");
}
In the following class, another class(not included) is called to fetch the tweets.
public class App implements Runnable {
private String threadName;
TwitterStream twitterStream = new TwitterStreamFactory().getTwitterStreamInstance();
TwitterStreamWorker streamWorker = new TwitterStreamWorker();
public App(String name) {
this.threadName = name;
}
public void appTwitter() {
String[] queryParams = { "Delhi" };
String[] queryLang = { "en" };
FilterQuery filterQuery = new FilterQuery();
FilterQuery query = filterQuery.getFilterQueryInstance(queryParams, queryLang);
System.out.println("Query " + query);
streamWorker.startStreamingWorker(twitterStream, query);
}
public void run() {
System.out.println("Running thread " + threadName);
appTwitter();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() {
// TODO Auto-generated method stub
}
}
I have also tried using newSingleThreadExecutor() but the problem remains the same.

Multi threaded java program to print even and odd numbers alternatively

I was asked to write a two-threaded Java program in an interview. In this program one thread should print even numbers and the other thread should print odd numbers alternatively.
Sample output:
Thread1: 1
Thread2: 2
Thread1: 3
Thread2: 4
... and so on
I wrote the following program. One class Task which contains two methods to print even and odd numbers respectively. From main method, I created two threads to call these two methods. The interviewer asked me to improve it further, but I could not think of any improvement. Is there any better way to write the same program?
class Task
{
boolean flag;
public Task(boolean flag)
{
this.flag = flag;
}
public void printEven()
{
for( int i = 2; i <= 10; i+=2 )
{
synchronized (this)
{
try
{
while( !flag )
wait();
System.out.println(i);
flag = false;
notify();
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
public void printOdd()
{
for( int i = 1; i < 10; i+=2 )
{
synchronized (this)
{
try
{
while(flag )
wait();
System.out.println(i);
flag = true;
notify();
}
catch(InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
}
public class App {
public static void main(String [] args)
{
Task t = new Task(false);
Thread t1 = new Thread( new Runnable() {
public void run()
{
t.printOdd();
}
});
Thread t2 = new Thread( new Runnable() {
public void run()
{
t.printEven();
}
});
t1.start();
t2.start();
}
}
I think this should work properly and pretty simple.
package com.simple;
import java.util.concurrent.Semaphore;
/**
* #author Evgeny Zhuravlev
*/
public class ConcurrentPing
{
public static void main(String[] args) throws InterruptedException
{
Semaphore semaphore1 = new Semaphore(0, true);
Semaphore semaphore2 = new Semaphore(0, true);
new Thread(new Task("1", 1, semaphore1, semaphore2)).start();
new Thread(new Task("2", 2, semaphore2, semaphore1)).start();
semaphore1.release();
}
private static class Task implements Runnable
{
private String name;
private long value;
private Semaphore semaphore1;
private Semaphore semaphore2;
public Task(String name, long value, Semaphore semaphore1, Semaphore semaphore2)
{
this.name = name;
this.value = value;
this.semaphore1 = semaphore1;
this.semaphore2 = semaphore2;
}
#Override
public void run()
{
while (true)
{
try
{
semaphore1.acquire();
System.out.println(name + ": " + value);
value += 2;
semaphore2.release();
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
}
}
}
Well, there are many alternatives. I would probably use a SynchronousQueue instead (I don't like low-level wait/notify and try to use higher-level concurrency primitives instead). Also printOdd and printEven could be merged into single method and no additional flags are necessary:
public class App {
static class OddEven implements Runnable {
private final SynchronousQueue<Integer> queue = new SynchronousQueue<>();
public void start() throws InterruptedException {
Thread oddThread = new Thread(this);
Thread evenThread = new Thread(this);
oddThread.start();
queue.put(1);
evenThread.start();
}
#Override
public void run() {
try {
while (true) {
int i = queue.take();
System.out.println(i + " (" + Thread.currentThread() + ")");
if (i == 10)
break;
queue.put(++i);
if (i == 10)
break;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) throws InterruptedException {
new OddEven().start();
}
}
Is there any better way to write the same program?
Well, the thing is, the only good way to write the program is to use a single thread. If you want a program to do X, Y, and Z in that order, then write a procedure that does X, then Y, then Z. There is no better way than that.
Here's what I would have written after discussing the appropriateness of threads with the interviewer.
import java.util.concurrent.SynchronousQueue;
import java.util.function.Consumer;
public class EvenOdd {
public static void main(String[] args) {
SynchronousQueue<Object> q1 = new SynchronousQueue<>();
SynchronousQueue<Object> q2 = new SynchronousQueue<>();
Consumer<Integer> consumer = (Integer count) -> System.out.println(count);
new Thread(new Counter(q1, q2, 2, 1, consumer)).start();
new Thread(new Counter(q2, q1, 2, 2, consumer)).start();
try {
q1.put(new Object());
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
private static class Counter implements Runnable {
final SynchronousQueue<Object> qin;
final SynchronousQueue<Object> qout;
final int increment;
final Consumer<Integer> consumer;
int count;
Counter(SynchronousQueue<Object> qin, SynchronousQueue<Object> qout,
int increment, int initial_count,
Consumer<Integer> consumer) {
this.qin = qin;
this.qout = qout;
this.increment = increment;
this.count = initial_count;
this.consumer = consumer;
}
public void run() {
try {
while (true) {
Object token = qin.take();
consumer.accept(count);
qout.put(token);
count += increment;
}
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
}
How about a shorter version like this:
public class OddEven implements Runnable {
private static volatile int n = 1;
public static void main(String [] args) {
new Thread(new OddEven()).start();
new Thread(new OddEven()).start();
}
#Override
public void run() {
synchronized (this.getClass()) {
try {
while (n < 10) {
this.getClass().notify();
this.getClass().wait();
System.out.println(Thread.currentThread().getName() + ": " + (n++));
this.getClass().notify();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
There is a bit of a trick to kick-start the threads properly - thus the need to an extra notify() to start the whole thing (instead of have both processes wait, or required the main Thread to call a notify) and also to handle the possibility that a thread starts, does it's work and calls notify before the second thread has started :)
My initial answer was non-functional. Edited:
package test;
public final class App {
private static volatile int counter = 1;
private static final Object lock = new Object();
public static void main(String... args) {
for (int t = 0; t < 2; ++t) {
final int oddOrEven = t;
new Thread(new Runnable() {
#Override public void run() {
while (counter < 100) {
synchronized (lock) {
if (counter % 2 == oddOrEven) {
System.out.println(counter++);
}
}
}
}
}).start();
}
}
}

Is my producer/consumer solution correct?

I'm trying to learn more about threads and thought that coming up with a solution to the producer/consumer problem would be a good start. One of the constraints I put on the solution was that the consumer does not know ahead of time how much the producer is producing. The code runs as expected and I've run it many many times, but that doesn't mean that it is free of flaws. Are there any problems with this solution?
package Multithreading.ProducerConsumer;
import java.util.LinkedList;
import java.util.concurrent.Semaphore;
public class ProducerConsumer
{
private class Producer implements Runnable
{
#Override
public void run()
{
for(int i = 0; i < 1000; i++)
{
try
{
canProduce.acquire();
mutex.acquire();
queue.add(i);
mutex.release();
canConsume.release();
}
catch (InterruptedException ex)
{
;
}
}
try
{
canConsume.acquire();
isTryingToFinish = true;
canConsume.release();
}
catch (InterruptedException ex)
{
;
}
}
}
private class Consumer implements Runnable
{
#Override
public void run()
{
while(!isDone)
{
try
{
canConsume.acquire();
mutex.acquire();
System.out.println(queue.pop());
if(isTryingToFinish && queue.isEmpty())
{
isDone = true;
}
mutex.release();
canProduce.release();
}
catch (InterruptedException ex)
{
;
}
}
}
}
Semaphore canProduce;
Semaphore canConsume;
Semaphore mutex;
boolean isTryingToFinish = false;
boolean isDone = false;
final static int bufferSize = 100;
LinkedList<Integer> queue;
public ProducerConsumer()
{
queue = new LinkedList<>();
canProduce = new Semaphore(bufferSize);
canConsume = new Semaphore(0);
mutex = new Semaphore(1);
}
public void Go() throws InterruptedException
{
Thread p = new Thread(new Producer());
Thread c = new Thread(new Consumer());
p.start();
c.start();
p.join();
c.join();
System.out.println("Job Complete!");
}
public static void main(String[] args) throws InterruptedException
{
ProducerConsumer p = new ProducerConsumer();
p.Go();
}
}
You could look at MSDN's 'Example 2: Synchronizing two threads: a producer and a consumer'. It's c# but that should not be a problem.

Wait until child threads completed : Java

Problem description : -
Step 1: Take input FILE_NAME from user at main thread.
Step 2: Perform 10 operations on that file (i.e count chars, count lines etc.. ), and all those 10 operations must be in septate threads. It means there must be 10 child threads.
Step 3: Main thread waits until all those child threads completed.
Step 4: Print result.
What I did :-
I did a sample code with 3 threads. I don't want file operation code from your side.
public class ThreadTest {
// This is object to synchronize on.
private static final Object waitObject = ThreadTest.class;
// Your boolean.
private static boolean boolValue = false;
public final Result result = new Result();
public static void main(String[] args) {
final ThreadTest mytest = new ThreadTest();
System.out.println("main started");
new Thread(new Runnable() {
public void run() {
System.out.println("Inside thread");
//Int initialiser
new Thread(new Runnable() {
public void run() {
System.out.println("Setting integer value");
mytest.result.setIntValue(346635);
System.out.println("Integer value seted");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
//String initialiser
new Thread(new Runnable() {
public void run() {
System.out.println("Setting string value");
mytest.result.setStringValue("Hello hi");
System.out.println("String value seted");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
//Boolean initialiser
new Thread(new Runnable() {
public void run() {
System.out.println("Setting boolean value");
mytest.result.setBoolValue(true);
System.out.println("Boolean value seted");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
System.out.println("Thread is finished");
//Notify to main thread
synchronized (ThreadTest.waitObject) {
ThreadTest.boolValue = true;
ThreadTest.waitObject.notifyAll();
}
}
}).start();
try {
synchronized (ThreadTest.waitObject) {
while (!ThreadTest.boolValue) {
ThreadTest.waitObject.wait();
}
}
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out.println("main finished");
System.out.println("Result is : " + mytest.result.toString());
}
}
Problem :-
My above code is not giving correct answer. How can I do that?
Alternate solutions:
CountDownLatch class does the same. But I don't want to use that class.
I looked this similar solution and I want to use methods of Thread only.
You can do:
Thread t = new Thread() {
public void run() {
System.out.println("text");
// other complex code
}
};
t.start();
t.join();
This way you will wait until the thread finishes and just then continue. You can join multiple threads:
for (Thread thread : threads) {
thread.join();
}
I would recommend looking at the Executors framework first, and then look into the CompletionService.
Then you can write something like this:
ExecutorService executor = Executors.newFixedThreadPool(maxThreadsToUse);
CompletionService completion = new ExecutorCompletionService(executor);
for (each sub task) {
completion.submit(new SomeTaskYouCreate())
}
// wait for all tasks to complete.
for (int i = 0; i < numberOfSubTasks; ++i) {
completion.take(); // will block until the next sub task has completed.
}
executor.shutdown();
In Java 8 a far better approach is to use parallelStream()
Note: it is far easier to see exactly what these background tasks are doing.
public static void main(String[] args) {
Stream.<Runnable>of(
() -> mytest.result.setIntValue(346635),
() -> mytest.result.setStringValue("Hello hi"),
() -> mytest.result.setBoolValue(true) )
.parallel()
.forEach(Runnable::run);
System.out.println("main finished");
System.out.println("Result is : " + mytest.result.toString());
}
I took out the debug information and the sleep as these don't alter the outcome.
You may want to choose CountDownLatch from java.util.concurrent. From JavaDocs:
A synchronization aid that allows one or more threads to wait until a
set of operations being performed in other threads completes.
Sample code:
import java.util.concurrent.CountDownLatch;
public class Test {
private final ChildThread[] children;
private final CountDownLatch latch;
public Test() {
this.children = new ChildThread[4];
this.latch = new CountDownLatch(children.length);
children[0] = new ChildThread(latch, "Task 1");
children[1] = new ChildThread(latch, "Task 2");
children[2] = new ChildThread(latch, "Task 3");
children[3] = new ChildThread(latch, "Task 4");
}
public void run() {
startChildThreads();
waitForChildThreadsToComplete();
}
private void startChildThreads() {
Thread[] threads = new Thread[children.length];
for (int i = 0; i < threads.length; i++) {
ChildThread child = children[i];
threads[i] = new Thread(child);
threads[i].start();
}
}
private void waitForChildThreadsToComplete() {
try {
latch.await();
System.out.println("All child threads have completed.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class ChildThread implements Runnable {
private final String name;
private final CountDownLatch latch;
protected ChildThread(CountDownLatch latch, String name) {
this.latch = latch;
this.name = name;
}
#Override
public void run() {
try {
// Implementation
System.out.println(name + " has completed.");
} finally {
latch.countDown();
}
}
}
public static void main(String[] args) {
Test test = new Test();
test.run();
}
}
Output:
Task 1 has completed.
Task 4 has completed.
Task 3 has completed.
Task 2 has completed.
All child threads have completed.
There are many ways to approach this. Consider CountDownLatch:
import java.util.concurrent.CountDownLatch;
public class WorkerTest {
final int NUM_JOBS = 3;
final CountDownLatch countDownLatch = new CountDownLatch(NUM_JOBS);
final Object mutex = new Object();
int workData = 0;
public static void main(String[] args) throws Exception {
WorkerTest workerTest = new WorkerTest();
workerTest.go();
workerTest.awaitAndReportData();
}
private void go() {
for (int i = 0; i < NUM_JOBS; i++) {
final int fI = i;
Thread t = new Thread() {
public void run() {
synchronized(mutex) {
workData++;
}
try {
Thread.sleep(fI * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
}
};
t.start();
}
}
private void awaitAndReportData() throws InterruptedException {
countDownLatch.await();
synchronized(mutex) {
System.out.println("All workers done. workData=" + workData);
}
}
}
Check if all child threads are dead, every n seconds. Simple, yet effective method:
boolean allDead=false;
while(! allDead){
allDead=true;
for (int t = 0; t < threadCount; t++)
if(threads[t].isAlive()) allDead=false;
Thread.sleep(2000);
}

Categories

Resources