ExecutorService does not block till the thread finishe - java

i have a class FeatOrientation and in that class in its constructor i perform two operations each one in a separate thread and i am using CountDownLatch so that, when gaussThread finishes the laplaceThread startes.
and in the main class that has the main method i am using ExecutorService and in the
".runAsync(new FeatOrientRun(bgrMat), featOrientExe);"
in the run method i call "calcFeatOrient" function and in that function i instantiate an object
from the FeatOrientation class. and the line
"CompletableFuture.allOf(future0).join();"
i used it to block the main thread till the two threads in the FeatOrientation class finih and then i do some calculation or display some data as in
"Log.D(TAG, "MainClass", "SmoothedImgList:" + fo.getSmoothedImgList().size());".
the problem is , at run time i receive the output shown below from the console despit the getSmoothedImgList is not empty. I knew that it is not empty by commenting out the following three lines:
featOrientExe = Executors.newFixedThreadPool(1);
future0 = CompletableFuture.runAsync(new FeatOrientRun(bgrMat), featOrientExe);
CompletableFuture.allOf(future0).join();//blocks the main thread till future0, and future1 finishes
featOrientExe.shutdown();
and i instantiated an object from the FeatOrientation class in the main method and then , made the main thread to sleep for 7 seconds and after the 7 seconds, i called the following lines
Log.D(TAG, "MainClass", "SmoothedImgList:" + fo.getSmoothedImgList().size());
Log.D(TAG, "MainClass", "SubSampledImgList:" + fo.getSubSampledImgList().size());
for (int i = 0; i < fo.getSmoothedImgList().size(); i++) {
ImageUtils.showMat(fo.getSmoothedImgList().get(i), "SmoothedImgList_" + i);
}
for (int i = 0; i < fo.getSubSampledImgList().size(); i++) {
//Mat laplaceImg = SysUtils.applyLaplac(fo.getSubSampledImgList().get(i));
//ImageUtils.showMat(laplaceImg, "getSubSampledImgList" + i);
}
and i received outout.
please let ma know what i am doing wrong with the ExecutorService, and why the approach i am following in the below posted code does not work desoite i wait till the FeatOrientation class finish it works.
console out put:
1: Error: FeatOrientation -> getSmoothedImgList: smoothedImgList is empty
Exception in thread "main" java.lang.NullPointerException
at com.example.featorientation_00.MainClass.main(MainClass.java:39)
main class:
public static void main(String[] args) {
MatFactory matFactory = new MatFactory();
FilePathUtils.addInputPath(path_Obj);
Mat bgrMat = matFactory.newMat(FilePathUtils.getInputFileFullPathList().get(0));
featOrientExe = Executors.newFixedThreadPool(1);
future0 = CompletableFuture.runAsync(new FeatOrientRun(bgrMat), featOrientExe);
CompletableFuture.allOf(future0).join();//blocks the main thread till future0, and future1 finishes
featOrientExe.shutdown();
Log.D(TAG, "MainClass", "SmoothedImgList:" + fo.getSmoothedImgList().size());
Log.D(TAG, "MainClass", "SubSampledImgList:" + fo.getSubSampledImgList().size());
for (int i = 0; i < fo.getSmoothedImgList().size(); i++) {
ImageUtils.showMat(fo.getSmoothedImgList().get(i), "SmoothedImgList_" + i);
}
for (int i = 0; i < fo.getSubSampledImgList().size(); i++) {
//Mat laplaceImg = SysUtils.applyLaplac(fo.getSubSampledImgList().get(i));
//ImageUtils.showMat(laplaceImg, "getSubSampledImgList" + i);
}
}
static class FeatOrientRun implements Runnable {
private Mat bgrMat;
public FeatOrientRun(Mat bgrMat) {
// TODO Auto-generated constructor stub
this.bgrMat = bgrMat;
}
public void run() {
// TODO Auto-generated method stub
calcFeatOrient(this.bgrMat);
}
}
public static void calcFeatOrient(Mat bgrMat) {
// TODO Auto-generated method stub
fo = new FeatOrientation(bgrMat);
}
FeatOrientation class:
public FeatOrientation(Mat bgrMat) {
// TODO Auto-generated constructor stub
this.origBGRImgList = new ArrayList<Mat>();
this.origGSImgList = new ArrayList<Mat>();
this.smoothedImgList = new ArrayList<Mat>();
this.downSampledImgList = new ArrayList<Mat>();
this.laplaceImgList = new ArrayList<Mat>();
this.latch = new CountDownLatch(1);
if (bgrMat != null) {
if (!bgrMat.empty()) {
if (bgrMat.channels() == 3) {
if ( (bgrMat.size().width >= SysConsts.MIN_IMG_WIDTH) && (bgrMat.size().height >= SysConsts.MIN_IMG_HEIGHT) ) {
this.bgrMat = bgrMat;
this.gaussThread = new Thread(new GaussRun(this.bgrMat, this.latch), "GAUSSIAN_THREAD");
this.laplaceThread = new Thread(new LaplaceRun(this.latch), "GAUSSIAN_THREAD");
this.gaussThread.start();
this.laplaceThread.start();
} else {
Log.E(TAG, "FeatOrientation", "the Mat you passed to the constructor has size: " + this.bgrMat.size() +
" the minimum width must = " + SysConsts.MIN_IMG_WIDTH +
" and the maximum height must = " + SysConsts.MIN_IMG_HEIGHT);
}
} else {
Log.E(TAG, "FeatOrientation", "BGR mat passed to the constructor does not has 3 channels.");
}
} else {
Log.E(TAG, "FeatOrientation", "BGR mat passed to the constructor is empty");
}
} else {
Log.E(TAG, "FeatOrientation", "the BGR mat you passed to the constructor is null");
}
}
class GaussRun implements Runnable {
private Mat bgrMat;
private CountDownLatch latch;
public GaussRun(Mat bgrMat, CountDownLatch latch) {
// TODO Auto-generated constructor stub
this.bgrMat = bgrMat;
this.latch = latch;
}
public void run() {
// TODO Auto-generated method stub
applyGaussianPyr(this.bgrMat);
this.latch.countDown();
}
}
class LaplaceRun implements Runnable {
private CountDownLatch latch;
public LaplaceRun(CountDownLatch latch) {
// TODO Auto-generated constructor stub
this.latch = latch;
}
public void run() {
// TODO Auto-generated method stub
try {
this.latch.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
applyLaplacianPyr();
}
}

Your collection is not thread safe so while the task may have finished, this doesn't mean the result is visible to another thread.
You could use a thread safe collection, but I prefer to return the results via Future<List<X>> and call list = future.get() This will both wait for the result and ensure it is passed in a thread safe manner regardless of which collection you use.
I assume this is just an example.
Running threads only makes sense if you have independent tasks (plural) to perform. It makes no sense to start one thread and wait for it's response, you may as well do the work in the current thread as it will be simpler and faster.

Related

static varibale cant be changed from a thread

in the below code, I create the class FMSHandler to process a string value passed to it from the main method as follwos
while (true) {
fmsHandler.process("param1_" + (++cnt) + ", param2_" + (cnt));
}
what i want to do is, to allow the processing to be performed every 3 seconds. or in other words, every 3 seconds i read the message passed from the main throught the previously mentioned code and perform
further processing. to do so, i created a static boolean variable called sIsProcessing to regulate the processing. this static variable is initially false and as long as there is
a message being processed it will be true and it will be set back to false when the thread the performs processing finihes as shown in the code below.
the problem i am facing is, despite the while-loop runs for ever, the processing is applied once and it is NOT repeated every 3 seconds as i expected it.
please have alook at the code and let me know where is the mistake
main:
public class Main {
private final static String TAG = Main.class.getSimpleName();
public static void main(String[] args) {
FMSHandler fmsHandler = new FMSHandler();
long startTime = TimeUtils.getTSSec();
int cnt = 0;
while (true) {
fmsHandler.process("param1_" + (++cnt) + ", param2_" + (cnt));
}
}
}
FMSHandler :
public class FMSHandler {
private final static String TAG = FMSHandler.class.getSimpleName();
private static boolean sIsProcessing = false;
private static int sCnt = 0;
public void process(String fmsMsg) {
if (!sIsProcessing) {
sIsProcessing = true;
Log.w(TAG, "FMSHandler", "new task to be processed");
new HandlerThread(HandlerThread.class.getSimpleName() + "_" + (FMSHandler.sCnt++), fmsMsg).start();
}
}
class HandlerThread extends Thread {
private String[] mSplittedFMS = null;
private String mThreadName = "";
public HandlerThread(String threadName, String fmsMsg) {
// TODO Auto-generated constructor stub
this.setName(threadName);
this.mSplittedFMS = this.toArray(fmsMsg);
}
private String[] toArray(String fmsMsg) {
// TODO Auto-generated method stub
return fmsMsg.split(",");
}
public void run() {
Log.w(TAG, "HandlerThread.run()", this.getName() + " started");
for (int i = 0; i < this.mSplittedFMS.length; i++) {
Log.i(TAG, "HandlerThread.run()", "this.mSplittedFMS: " + this.mSplittedFMS[i]);
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.w(TAG, "HandlerThread.run()", this.getName() + " finished");
sIsProcessing = false;
}
}
}
You should declare the sIsProcessing variable as volatile or use an AtomicBoolean.
Also, currently, a lot of the messages passed to process(...) will be skipped, I'm not sure if that is your intention.
If you want to prevent messages from being skipped you will need to use synchronization to block the loop from the main thread while a message is being processed.
My suggestion will be to completely rewrite this and use a Timer and some kind of queue from the concurrency package like ArrayBlockingQueue.
Here is an example:
public static final ArrayBlockingQueue<String> messages = new ArrayBlockingQueue<>(100);
public static final AtomicBoolean keepRunning = new AtomicBoolean(true);
.....
new Thread(new Runnable(){
public void run(){
while(keepRunning.get()){
String message = messages.take();// blocks until a message is avaiable
synchronized(Thread.currentThread()){
Thread.currentThread().wait(3000);// pause 3 seconds before starting to process the next message.
}
}
}
}).start();
// add messages from some other class;
MessagesProcessor.messages.add("some message");

Executing Thread by run method and Start method

I am trying to execute Thread into the Both method using thread.Run and as well as thread.start
Here the case
Main Class
Thread thread = new GetTimeZones();
ByImletingInterface thread21 = new ByImletingInterface();
thread21.getMailStarttime(5);
ByImletingInterface thread2 = new ByImletingInterface();
thread2.getMailStarttime(10);
thread.start();
new Thread(thread21).start();
new Thread(thread2).start();
Thread 1
public class ByImletingInterface implements Runnable {
private int starttime;
#Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(starttime * 1000);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
System.out.println("Checking Mail");
}
}
and Other therad
public class GetTimeZones extends Thread {
#SuppressWarnings("static-access")
#Override
public void run() {
// TODO Auto-generated method stub
Locale locale;
DateFormat timeforMatter;
DateFormat dateforMatter;
String timeoutput = null;
String dateoutput = null;
try {
java.util.Date date;
for (int i = 0; i < 20; i++) {
date = new Date();
locale = new Locale("en");
timeforMatter = DateFormat.getTimeInstance(DateFormat.DEFAULT,
locale);
dateforMatter = DateFormat.getDateInstance(DateFormat.DEFAULT,
locale);
//System.out.println(timeforMatter);
timeoutput = timeforMatter.format(date);
dateoutput = dateforMatter.format(date);
System.out.println(timeoutput);
System.out.println(dateoutput);
System.out.println();
try {
Thread.sleep(2000);
} catch (Exception e) {
// TODO: handle exception
}
}
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
e.printStackTrace();
}
super.run();
}
}
how ever for describing my prob both class is not needed but still m giving it.
when i use therad.start into main class like i did. Its sententiously executing three of threads.
But when i use theread.run one by one thred is exected. means its synchronize. Why this happens?
When you call the run() method, you are running it on the current thread, so of course it will run one by one, as there is only one thread (each run() method will be executed after the previous one is done).
Only when you call start() a new thread is created and the run() method is executed in that new thread.

Java Future object with Runnable interface

I have to do an assignment where I have to implement a background thread logger for a web service, for the logger we got some skeleton code where we have a run method and a method that returns a future object. For logging of activities we have to implement write ahead logging, I managed to start a new thread for the logger and I send it the command to log something when I execute an insert/update command in the web service (the web service implements a key to values map), but I can`t manage to make the main thread wait for the logging thread to finish logging. Does anybody have any suggestions? Maybe I am doing something wrong?
public class IndexImpl implements Index<KeyImpl,ValueListImpl>
{
private Thread log_thread;
private MyLogger log;
/*
* in out pair, the long refers to the initial memory address that our data
* has been saved too, and the integer refers to the length of the data in the file
*/
private HashMap<KeyImpl,Pair<Long,Integer>> m;
private long endAddr;
public IndexImpl()
{
valSer = new ValueSerializerImpl();
endAddr = 0;
m = new HashMap<KeyImpl,Pair<Long,Integer>>();
this.log= new MyLogger();
this.log_thread= new Thread(log);
log_thread.start();
}
public void insert(KeyImpl k, ValueListImpl v) throws KeyAlreadyPresentException, IOException {
locker.WriteLock(k);
try {
if (m.containsKey(k)) {
throw new KeyAlreadyPresentException(k);
}
else {
//LOGGING
Object[] array = new Object[3]; // Key, Old Value List, New Value List
array[0]= k.toString(); //Key
array[1]= null; // Old value list
array[2]= v; // New value list
LogRecord l = new LogRecord(MyKeyValueBaseLog.class, "insert", array);
FutureLog<LogRecord> future = (FutureLog<LogRecord>) log.logRequest(l);
System.out.println("Inserting a new key " + k.getKey());
future.get();
long tempEndAddr;
byte[] temp = valSer.toByteArray(v);
//we are using the ReentrantReadWriteLock implementation found in java
write.lock();
try{
tempEndAddr = endAddr;
endAddr += temp.length;
}
finally{
write.unlock();
}
store.write(tempEndAddr, temp);
m.put(k, new Pair<Long, Integer>(tempEndAddr,temp.length));
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
locker.WriteUnlock(k);
}
}
And the code for the logger is :
public class MyLogger implements Logger {
private ArrayList<LogRecord> log = new ArrayList<LogRecord>(100);
public MyLogger()
{
}
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("This is the logger thread! " + Thread.currentThread());
}
#Override
public Future<?> logRequest(LogRecord record) {
// TODO Auto-generated method stub
this.log.add(record);
System.out.println("Record added to log! operation: " + record.getMethodName() );
FutureLog<LogRecord> future = new FutureLog();
return future;
}
}
Your logger thread is started and will exit immediately
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("This is the logger thread! " + Thread.currentThread());
}
Instead, you need to loop in this method, writing log records as they come in. I would perhaps suggest reading from a BlockingQueue, and the method logRequest() should add log records to this queue. That way your run() method will just wait on the queue (using the take() method provided by the queue) and write out each record as it takes it off the queue.
You'll need to be able to stop this, and perhaps interrupting the thread is a solution here.
All of the above is simply one implementation choice. The fundamental problem you have is that your thread starts/stops almost instantaneously.

Invoke more than one webservice using separate thread in java?

I have to call more than one webservice in one method each webservice is executed by separate thread in concurrent/parellel. Every web service will return one ArrayList. Note: may chance some webservices will fail or take more time process response in this case i have to skip these failure result. How can I achieve this? I tried this sample code.
public class MultiThreadsEx{
public class Task implements Runnable {
private Object result;
private String id;
int maxRowCount = 0;
public Task(String id) {
this.id = id;
}
public Object getResult() {
return result;
}
public void run() {
try {
System.out.println("Running id=" + id+" at "+Utilities.getCurrentJavaDate("DD/MM/YYYY HH:MM:SS"));
if(id.equalsIgnoreCase("1")){
/**Getting Details from Amazon WS*/
maxRowCount = AmazonUtils.getweather(cityname);
}else if(id.equalsIgnoreCase("2")){
/**Getting Details from Google WS* /
maxRowCount = GoogleUtils.getWeather(cityName);
}
// call web service
//Thread.sleep(1000);
//result = id + " more";
result = maxRowCount;
} catch (InterruptedException e) {
// TODO do something with the error
throw new RuntimeException("caught InterruptedException", e);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void runInParallel(Runnable runnable1, Runnable runnable2) {
try {
Thread t1 = new Thread(runnable1);
Thread t2 = new Thread(runnable2);
t1.start();
t2.start();
} catch (Exception e) {
// TODO do something nice with exception
throw new RuntimeException("caught InterruptedException", e);
}
}
public void foo() {
try {
Task task1 = new Task("1");
Task task2 = new Task("2");
runInParallel(task1, task2);
System.out.println("task1 = " + task1.getResult()+" at "+Utilities.getCurrentJavaDate("DD/MM/YYYY HH:MM:SS"));
System.out.println("task2 = " + task2.getResult()+" at "+Utilities.getCurrentJavaDate("DD/MM/YYYY HH:MM:SS"));
} catch (Exception e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
But run() return type is void so how can return result? Examples are highly appreciated. I am new to multithread/concurrent threads concept so if I'm doing anything wrong, please point me in the right direction.
Consider replacing Runnable - run with Callable - call. This will allow you to return a result from your thread task:
public class Task implements Callable<Object> {
private Object result;
public Object call() {
// compute result
return result;
}
}
Now use an ExecutorService:
public static void runInParallel(Callable<Object> c1, Callable<Object> c2) {
ExecutorService exec = Executors.newFixedThreadPool(2);
Future<Object> f1 = exec.submit(c1);
Future<Object> f2 = exec.submit(c2);
}
Later in the code you can use f1.get() and f2.get() to wait for the results of the tasks.
The usual way to communicate the results of a Runnable back to the object which created it is by passing the creating object to the constructor of the Runnable. When the task is finished, you can call a method in the creating object and pass the result data.

multithreading in Java with 2 threads spawned

I wrote a Multithreaded program in Java given below :-
public class Client {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Counter counter = new Counter();
int val = counter.getValue();
while(val < 5){
val = counter.getValue();
System.out.println("In main thread : "+val);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Counter implements Runnable {
private int countValue;
Counter(){
countValue = 0;
Thread thread = new Thread(this ,"Counter A");
Thread thread1 = new Thread(this ,"Counter B");
thread.start();
thread1.start();
}
int getValue(){
return countValue;
}
#Override
public void run() {
// TODO Auto-generated method stub
while( countValue < 5){
System.out.println("In child thread : "+ ++countValue );
try {
Thread.sleep(250);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
and output of program is
output :-
In main thread : 0
In child thread : 2
In child thread : 1
In child thread : 3
In child thread : 3
In child thread : 4
In child thread : 5
In main thread : 5
Can anybody explain me in detail how this output came.Thank you in advance
You have 3 threads (main and 2 child) that are all running in parallel (unless you have a single proc box) that are all reading and writing a resource countValue that isn't protected by any kind of synchronization.
When you do things like this, you'll get apparently random output.

Categories