JVM does not exit when TimeoutException occurs - java

I have code which needs to do something like this
There is a list of classes each with some method (lets say execute()). I need to invoke that method on each class and there is a fixed timeOut for each invocation. Now, one of the class's execute method is badly written and results in a timeout due to which the jvm does not exit. I am running the class like this.
java ExecutorServiceTest execute TestClass1 TestClass2 TestClass3
Why does the jvm not exit after completing the execution of the code?
I get the following output
In class 1
In Class 2
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at ExecutorServiceTest.main(ExecutorServiceTest.java:78)
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
The second class's execute times out and after that, the third class's execute also times out. Why does the third class's execute time out?
The jvm does not exit after the execution is complete. What is the reason? Also why is the TestClass3 execute timedout?
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
class Task implements Callable<String> {
Object instance;
Method m;
Object[] input;
Task(Object instance, Method m, Object[] input) {
this.instance = instance;
this.m = m;
this.input = input;
}
public String call() {
String s = "initial";
try {
m.invoke(instance, input);
}
catch (RuntimeException e) {
}
catch (Exception e) {
}
finally {
}
return s;
}
}
public class ExecutorServiceTest {
public static void main(String[] args) {
String methodName = args[0];
String className;
List<Object> instanceList = new ArrayList<Object>();
for (int i=1;i<args.length;i++) {
className = args[i];
Object o = null;
try {
o = Class.forName(className).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
instanceList.add(o);
}
ExecutorService executor = Executors.newSingleThreadExecutor();
Iterator<Object> iter = instanceList.iterator();
while (iter.hasNext()) {
Object o = iter.next();
Method m = null;
try {
m = o.getClass().getDeclaredMethod(methodName, new Class[] {});
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Task t = new Task(o,m,new Object[]{});
Future<String> fut = executor.submit(t);
try {
fut.get(2,TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
executor.shutdown();
}
}
public class TestClass1 {
public void execute() {
System.out.println("In class 1");
}
}
public class TestClass2 {
public void execute() {
System.out.println("In class 2");
boolean b = true;
while (b) {
}
}
}
public class TestClass3 {
public void execute() {
System.out.println("In class 3");
}
}

ExecutorService.shutdown() doesn't actually stop any running executors/threads, it just tells the service to stop accepting new tasks:
void shutdown()
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
Your TestClass2 instance is never going to stop running because it has a while(true) loop which is never halted.
If you want to stop the ExecutorService immediately, you can use awaitTermination(long timeout, TimeUnit unit) or shutdownNow().

You need to call executor.shutdown() or create a daemon thread (using appropriate ThreadFactory passed to Executors.newSingleThreadExecutor()

Related

Object located in the main thread is not initialized by another thread

I put together a class of an client app that should connect to a socket and it should automatically retrieve a DefaultTreeModel from the server or a simple String object as a test. The issue is that inside the main RemoteNetworking class the DefaultTreeModel or the String are successfully received but if I try to get them using getClientTreeModel() or verifiFromOutside i'm getting only null objects. Can you please help me understand this behavior? I'll place the code bellow.
package Networking;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public class RemoteNetworking extends Thread{
private volatile Socket remoteSocket;
private volatile boolean isRunning = true;
private Thread currentThread;
private volatile ObjectOutputStream oos;
private volatile ObjectInputStream ois;
private volatile DefaultTreeModel treeModel = null;
private String IP;
private int port;
private static volatile String test;
public RemoteNetworking(String IP, int port) {
this.IP = IP;
this.port = port;
}
public void connect() {
try {
SocketAddress socketAddress = new InetSocketAddress(IP, port);
remoteSocket = new Socket();
remoteSocket.connect(socketAddress);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private synchronized void setReceivedTreeModel(DefaultTreeModel receivedTreeModel) {
this.treeModel = receivedTreeModel;
}
public synchronized void disconnect() {
try {
//oos.writeObject("Disconnect");
oos.flush();
//oos.close();
isRunning = false;
remoteSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized DefaultTreeModel getClientTreeModel() {
return treeModel;
}
public synchronized void verifyFromOutside() {
System.out.println(test);
}
#Override
public void run() {
connect();
synchronized(this) {
this.currentThread = Thread.currentThread();
}
try {
ois = new ObjectInputStream(remoteSocket.getInputStream());
oos = new ObjectOutputStream(remoteSocket.getOutputStream());
oos.writeObject("DataTree");
oos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(isRunning) {
try {
Object object = (Object)ois.readObject();
/*if(object instanceof DefaultTreeModel) {
//this received object is not null
setReceivedTreeModel((DefaultTreeModel)object);
if(treeModel==null) {
System.out.println("Null object in RemoteNetworking");
}
verifyFromOutside();
}*/
if(object instanceof String) {
this.test = (String)object;
System.out.println(test);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

Java mqtt concurrent connections is taking time

I am trying to make the concurrent session to MQTT server and all clients will disconnect once all the connections are made.
In the below publisher code I am trying to make concurrents sessions each sending 50 messages. And like this 500 threads will create and each will send 50 messages. But for creating 100 connections it is taking 10 minutes. Is there any mistake in coding and is it possible to decrease the rate of connection speed changing in below code, because the same thing I have written in Golang the rate of connection is high there.
Below is the publisher code:
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.eclipse.paho.client.mqttv3.MqttSecurityException;
import org.eclipse.paho.client.mqttv3.MqttTopic;
public class Publisher extends Thread{
public static final String test_topic = "test";
private MqttClient client;
public static final String BROKER_URL = "tcp://192.168.1.129:1883";
CountDownLatch latch;
public Publisher(CountDownLatch latch) {
super();
this.latch = latch;
}
public void Publisher() {
String clientid=Thread.currentThread().getName();
System.out.println("=========== "+clientid);
MqttConnectOptions options = null;
try {
client = new MqttClient(BROKER_URL, clientid);
options = new MqttConnectOptions();
options.setCleanSession(true);
options.setMaxInflight(50);
client.connect(options);
} catch (MqttException e) {
try {
client.connect(options);
} catch (MqttSecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (MqttException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
//System.exit(1);
}
}
#Override
public void run() {
// TODO Auto-generated method stub
Publisher();
System.out.println(Thread.currentThread().getName());
try {
for(int i=0;i<50;i++)
{
//Thread.sleep(20);
publishTemperature();
}
} catch (MqttPersistenceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MqttException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} /*catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
public void publishTemperature() throws MqttPersistenceException, MqttException {
final MqttTopic test = client.getTopic(test_topic);
final String temperature=""{\"test\":\"test\"}"";
test.publish(new MqttMessage(temperature.getBytes()));
//System.out.println("Published data. Topic: " + "test" + " Message: " + temperature);
}
public MqttClient getClient() {
return client;
}
public void setClient(MqttClient client) {
this.client = client;
}
}
Below is the main method:
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
public class test {
static Publisher[] Publisher=null;
public static void main(String[] args) throws MqttPersistenceException, MqttException, InterruptedException {
final CountDownLatch latch = new CountDownLatch(50);
Publisher = new Publisher[500];
for(int i=0;i<500;i++)
{
Thread.sleep(10);
Publisher[i]=new Publisher(latch);
Publisher[i].start();
}
latch.await();
for(int i=0;i<500;i++)
{
//Thread.sleep(10);
Publisher[i].getClient().disconnectForcibly(25);
}
}
}
Here all connections will connect and make persistent connection up to reaching 500 connections. After that, all connections will disconnect once.
Remove the following line:
Publisher[i].join();
The docs for Thread.join() say the following:
public final void join()
throws InterruptedException
Waits for this thread to die.
An invocation of this method behaves in exactly the same way as the
invocation
join(0)
This means that every time round the loop it will stop and wait for that thread to complete it's task before creating the new one.
If you remove that call it will allow all the threads to run in parallel.

exception handling in executor service

When I throw exception from student name archana.
As per my understanding InvokeAll waits for all task to be completed and then return future list
Output I get is
pool-1-thread-1 Helloprerna
pool-1-thread-2 Helloabc
HELLO SOMEERROR
Execution Completed
I want other tasks output to be show for which exception is not thrown.Any suggestions
public class Executor {
public static void main(String args[]) throws InterruptedException{
ExecutorService executor=Executors.newFixedThreadPool(5);
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("prerna"));
list.add(new Student("abc"));
list.add(new Student("archana"));
list.add(new Student("def"));
list.add(new Student("xyz"));
list.add(new Student("ritu"));
list.add(new Student("babita"));
try {
List<Future<String>> resultList=executor.invokeAll(list);
for(Future<String> f:resultList){
//if(f.isDone()){
System.out.println(f.get());
//}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (ExecutionException e) {
// TODO Auto-generated catch block
System.out.println("HELLO SOME ERROR");
//e.printStackTrace();
}
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("Execution Completed");
}
}
.
public class Student implements Callable<String>{
String name;
public Student(String name) {
super();
this.name = name;
}
#Override
public String call() throws Exception {
// TODO Auto-generated method stub
if(name=="archana"){
throw new Exception();
}
return display(name);
}
private String display(String name2) {
try {
// System.out.println(Thread.currentThread().getName());
name2=Thread.currentThread().getName()+" Hello"+ name;
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return name2;
}
}
You can move around the try/catch:
Original:
try {
List<Future<String>> resultList=executor.invokeAll(list);
for(Future<String> f:resultList){
// if(f.isDone()){
System.out.println(f.get());
//}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (ExecutionException e) {
// TODO Auto-generated catch block
System.out.println("HELLO SOME ERROR");
// e.printStackTrace();
}
will be rather:
try {
List<Future<String>> resultList=executor.invokeAll(list);
for(Future<String> f:resultList){
try{
System.out.println(f.get());
}catch (ExecutionException e) {
System.out.println("HELLO SOME ERROR: " + e.getMessage());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
So here you will get all OK results and you can handle the exceptional execution for each task.
The pattern for this should be: Main thread create and call slaves threads, which should return ok value or error value (if there was any error). Then Main thread should collect results from slaves and process them.

OSGI bundle and threads

I am new in OSGI and i have current aim. I have 10 threads, it's writing their names in a file. After recording thread sleep random 0..1 sec. This all must be a bundle. I create it, but i'm not sure Is this correct. Can any comments?
package helloworld;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import writer.StartThreads;
public class Activator implements BundleActivator {
public void start(BundleContext context) throws Exception {
System.out.println("Start Thred!!");
new StartThreads().Execute();
}
public void stop(BundleContext context) throws Exception {
System.out.println("Goodbye World!!");
}
}
1
package writer;
import writer.WriterLogs;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class StartThreads {
public static void Execute() {
BufferedWriter writer = null;
File textFile = new File("threadLog.txt");
// if file doesnt exists, then create it
if (!textFile.exists()) {
try {
textFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
writer = new BufferedWriter(new FileWriter(textFile, true));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
WriterLogs wrt = new WriterLogs(writer);
Thread worker = new Thread(wrt);
worker.setName("Nisha-" + i);
worker.start();
try {
worker.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2
package writer;
import java.io.BufferedWriter;
import java.io.IOException;
public class WriterLogs implements Runnable {
private BufferedWriter writer;
public WriterLogs(BufferedWriter wr) {
this.writer = wr;
}
#Override
public void run() {
try
{
try {
synchronized(this.writer) {
this.writer.write(Thread.currentThread().getName() + "\n");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// set random 0...1 s.
Thread.sleep((long)(Math.random() * 1000));
System.out.println(Thread.currentThread().getName());
}
catch (InterruptedException interruptedException)
{
/*Interrupted exception will be thrown when a sleeping or waiting
* thread is interrupted.
*/
System.out.println( Thread.currentThread().getName() +interruptedException);
}
}
}
This is not correct. Like Boris the Spider states, when your bundle stops, you should free any resources and stop any processing the bundle was doing. So from the stop method you should somehow signal your threads to stop as soon as they can.
In practice you might get away with letting the code run, but this is definitely not how you should write your code in OSGi (which is what you're asking).

Program won't run because variables "may be uninitialized"?

I'm trying to make a new thread for parsing xml from an rss feed. When I click run it says there are errors please correct them etc. I have 2 classes in my project. The other class has no errors and this class below has only warnings that a lot of the things in the try/catch statements may be uninitialized. I understand that and figured I should still be able to run the program anyways, I expect them to be initialized and if they're not that's fine I want to know about it. Is this really what's going on or am I missing something? I thought it would compile if something may be uninitialized but its not certainly uninitialized.
public class RssParse extends Thread {
Thread th=new Thread() {
public void run(){
System.out.println("1");
URL iotd;
try {
iotd = new URL("http://www.nasa.gov/rss/image_of_the_day.rss");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("2");
BufferedReader in;
try {
in = new BufferedReader(new InputStreamReader(iotd.openStream()));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("3");
XmlPullParserFactory factory;
try {
factory = XmlPullParserFactory.newInstance();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
factory.setNamespaceAware(true);
System.out.println("4");
XmlPullParser xpp;
try {
xpp = factory.newPullParser();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("5");
try {
xpp.setInput(in);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("6");
int eventType;
try {
eventType = xpp.getEventType();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(eventType+"!!!!!!!!!!!!!!!!");
while(eventType!=XmlPullParser.END_DOCUMENT){
if(eventType==XmlPullParser.START_DOCUMENT){
System.out.println("start");
}
}
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}//method
};//thread
}//class
Look at this try/catch block for example :
URL iotd;
try {
iotd = new URL("http://www.nasa.gov/rss/image_of_the_day.rss");
} catch (MalformedURLException e) {
e.printStackTrace();
}
If iotd = new URL("...") fails, iotd will remain uninitialized.
There are two ways to deal with this :
Assign a default value to iotd, like : URL iotd = null; However, it's bad here because if you use iotd later its value may be null and can throw a NullPointerException.
Stop the execution of your function if something failed instead of just printing the stack trace. For example you can add a return statement in the catch block :
URL iotd;
try {
iotd = new URL("http://www.nasa.gov/rss/image_of_the_day.rss");
} catch (MalformedURLException e) {
e.printStackTrace();
return;
}
All the warnings you are getting are because all your catch blocks are not dealing with the exception at all (just printing the stacktrace to standard out).
Let's see it through an example:
URL iotd;
try {
iotd = new URL("http://www.nasa.gov/rss/image_of_the_day.rss");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
at that snipped you are declaring a iotd variable as a URL but without initializing it (not assigning any value), you do it inside the try block - which isn't wrong by the way. However if for any reason the statement inside the try block throws an exception program flow will go to the catch block leaving the iotd variable with its initial value (unassigned).
So, in that case, execution of the program will continue and when reaching this statement:
in = new BufferedReader(new InputStreamReader(iotd.openStream()));
it will find no value assigned to the iotd variable.
To remove the warning regarding the uninitialized value you can either assign a null value to the variable when declaring it or rethrow another exception inside the catch block, stopping the program flow.
In the other hand, the snippet you posted here is not just one class, it's actually two as you are extending the Thread class and then creating an anonymous one inside its body. Using threads is easier than that in Java, just implement the Runnable interface and then instantiate a new thread from that interface:
public class MyRunnable implements Runnable {
public void run() {
// do stuff
}
}
and then:
new Thread(new MyRunnable()).start();
cheers
you need to initialize the variables above the try catch block, or give them a value in catch or finally block
find updated code here
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
public class RssParse extends Thread {
Thread th=new Thread() {
public void run(){
System.out.println("1");
URL iotd=null;
try {
iotd = new URL("http://www.nasa.gov/rss/image_of_the_day.rss");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("2");
BufferedReader in=null;
try {
in = new BufferedReader(new InputStreamReader(iotd.openStream()));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("3");
XmlPullParserFactory factory=null;
try {
factory = XmlPullParserFactory.newInstance();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
factory.setNamespaceAware(true);
System.out.println("4");
XmlPullParser xpp=null;
try {
xpp = factory.newPullParser();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("5");
try {
xpp.setInput(in);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("6");
int eventType=-1; // set to a default value of your choice
try {
eventType = xpp.getEventType();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(eventType+"!!!!!!!!!!!!!!!!");
while(eventType!=XmlPullParser.END_DOCUMENT){
if(eventType==XmlPullParser.START_DOCUMENT){
System.out.println("start");
}
}
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}//method
};//thread
}//class

Categories