Could someone please help me to understand why do I need to use (inner) try catch if the method is declared as throwing the same exception.
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
producer();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t1.start();
t1.join();
}
syntax of producer() is
private static void producer() throws InterruptedException
The answer is that you are defining an anonymous class.
Thread t1 = new Thread(new Runnable() {
public void run() {
try {
producer(); //This is called in run method!
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
The declaration of the method that calls producer() is public void run() and this method does not throw the checked exception. Therefore, you have to catch it.
It's logical, because you start new thread, which can live after execution leaves the creating method(if it wasn't main method and if you didn't use Thread.join()). So you should handle exception independently.
Related
I'm trying to implement a method that continuously run a SQL query until it returns results or fails after x seconds.
Currently my method uses CountDownLatch:
final CountDownLatch done = new CountDownLatch(1);
new Thread(new Runnable()
{
#Override
public void run() {
try
{
getQueryResults(sql);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
done.countDown();
}
}).start();
return done.await(30, TimeUnit.SECONDS);
Are there better ways of doing this?
The below program is supposed to print even and odd numbers by two different threads but I am getting illegal monitor exception on notify method in the below code :
public class oddeven {
static volatile Integer t = 0;
public static void main(String as[]) {
oddrunnable or = new oddrunnable(t);
evenrunnable er = new evenrunnable(t);
Thread t1 = new Thread(or, "odd");
Thread t2 = new Thread(er, "even");
t1.start();
t2.start();
}
}
class oddrunnable implements Runnable {
Integer t;
public oddrunnable(Integer t) {
this.t = t;
}
#Override
public void run() {
// TODO Auto-generated method stub
synchronized (t) {
while (true) {
if (t % 2 == 0) {
try {
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Current thread id " + Thread.currentThread().getName());
t++;
t.notify();
}
}
}
}
class evenrunnable implements Runnable {
Integer t;
public evenrunnable(Integer t) {
this.t = t;
}
#Override
public void run() {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
synchronized (t) {
while (true) {
if (t % 2 != 0) {
try {
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Current thread id " + Thread.currentThread().getName());
t++;
t.notify(); // <-------------------exception on this line
}
}
}
}
the notify method is called on the synchronized object itself. Not sure why this is coming :
Current thread id even
Exception in thread "even" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at evenrunnable.run(oddeven.java:86)
at java.lang.Thread.run(Thread.java:619)
Integers in java wrapper are immutable, so as soon as you do t++, you are going to assign a new Integer object which you didn't took lock against and hence you get IllegalMonitorStateException.
Instead of Integer, use AtomicInteger and then use incrementAndGet api to increment the value of counter.
The problem is in using Integer object for synchronization and than doing increment(++) operation on it. I think its creating new integer object and than all the synchronized logic is going for toss. I am not sure about it as while debugging your code, eclipse was not showing whether it created new object.
A better alternative is to use some wrapper object around your integer or AtomicInteger class. Here is your code with AtomicInteger class used
public class oddeven {
static volatile AtomicInteger t = new AtomicInteger(0);
public static void main(String as[]) {
oddrunnable or = new oddrunnable(t);
evenrunnable er = new evenrunnable(t);
Thread t1 = new Thread(or, "odd");
Thread t2 = new Thread(er, "even");
t1.start();
t2.start();
}
}
class oddrunnable implements Runnable {
AtomicInteger t;
public oddrunnable(AtomicInteger t) {
this.t = t;
}
#Override
public void run() {
// TODO Auto-generated method stub
synchronized (t) {
while (true) {
if (t.intValue() % 2 == 0) {
try {
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Current thread id " + Thread.currentThread().getName());
t.incrementAndGet();
t.notify();
}
}
}
}
class evenrunnable implements Runnable {
AtomicInteger t;
public evenrunnable(AtomicInteger t) {
this.t = t;
}
#Override
public void run() {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
synchronized (t) {
while (true) {
if (t.intValue() % 2 != 0) {
try {
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Current thread id " + Thread.currentThread().getName());
t.incrementAndGet();
t.notify(); // <-------------------exception on this line
}
}
}
}
This question already has answers here:
Java InputStream blocking read
(7 answers)
Closed 8 years ago.
I have written a sample program to illustrate the working with pipe is thread. I have created 2 threads.
Thread1 is sending "Hi this is thread1" and call wait() for thread 2 to complete.
Thread2 is printing the message sent by thread1 and also will also append into a string buffer, then once the entire message is received, thread2 will print the contents of string buffer and will call notify. Now after calling wait() and notify both threads tend to be in deadlock
Strangely, thread2 prints the message one but does not print the contents of string buffer.
package com.tuto.MultiThreading;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipeExample {
public static void main(String[] args) throws IOException, InterruptedException {
final Object obj=new Object();
final PipedOutputStream pipeoutstream=new PipedOutputStream ();
final PipedInputStream pipeinputstream=new PipedInputStream(pipeoutstream);
Thread thread1= new Thread(new Runnable()
{
public void run() {
try {
pipeoutstream.write("Hello I am thread1".getBytes());
synchronized (obj)
{
obj.wait();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
pipeoutstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
try {
int data = pipeinputstream.read();
StringBuffer sb=new StringBuffer();
while(data != -1){
System.out.print((char) data);
sb.append((char)data);
data = pipeinputstream.read();
}
System.out.println();
System.out.println(sb.toString());
synchronized (obj) {
obj.notify();
}
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
pipeinputstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.exit(1);
}
}
OUTPUT::
Hello I am thread1
Updated Resolution:
package com.tuto.MultiThreading;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipeExample {
public static void main(String[] args) throws IOException, InterruptedException {
final Object obj=new Object();
final PipedOutputStream pipeoutstream=new PipedOutputStream ();
final PipedInputStream pipeinputstream=new PipedInputStream(pipeoutstream);
Thread thread1= new Thread(new Runnable()
{
public void run() {
try {
pipeoutstream.write("Hello I am thread1".getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
pipeoutstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (obj)
{
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
try {
int data = pipeinputstream.read();
StringBuffer sb=new StringBuffer();
while(data != -1){
System.out.print((char) data);
sb.append((char)data);
data = pipeinputstream.read();
}
System.out.println();
System.out.println(sb.toString());
synchronized (obj) {
obj.notify();
}
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
pipeinputstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.exit(1);
}
}
Now i am a bit more confused. I just moved wait() from try catch to finally. How did it affect the blocking of Pipestream?
The problem is that
data = pipeinputstream.read();
in thread 2 is a blocking call. From the javadoc of PipedInputStream#read()
This method blocks until input data is available, the end of the
stream is detected, or an exception is thrown.
Thread 2 keeps waiting until one of those things happen. Since none of them will ever happen, the thread will not be able to notify the other.
This is not deadlock.
Note that even if that call unblocked and returned -1, thread 2 could still execute its notify before your thread 1 called wait. In which case, thread 1 would be a in a constant waiting state and your program would not terminate.
class firstThread extends Helper1
{
Thread thread_1 = new Thread(new Runnable()
{
#Override
public void run() {
try {
for (int i = 1; i <= 20; i++) {
System.out.println("Hello World");
Thread.sleep(500);
if (i == 10) {
Notify();
Wait();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
class secondThread extends firstThread
{
Thread thread_2 = new Thread(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
Wait();
for(int i = 1; i<=20; i++)
{
System.out.println("Welcome");
Thread.sleep(100);
}
Notify();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
class Helper1
{
public synchronized void Wait() throws InterruptedException
{
wait();
}
public synchronized void Notify() throws InterruptedException
{
notify();
}
}
public class InheritanceClass {
public static void main(String[] args)
{
Thread f = new Thread(new firstThread().thread_1);
Thread s = new Thread(new secondThread().thread_2);
f.start();
s.start();
}
}
Only the first Thread has an output. Please try my code. I don't know why it happens.
The second thread does not give output, I suppose it's because of Wait() in the secondThread, I don't know what to do.
The problem is with the following code:
class Helper1
{
public synchronized void Wait() throws InterruptedException
{
wait();
}
public synchronized void Notify() throws InterruptedException
{
notify();
}
}
Above, the wait() and notify() calls are equivalent to this.wait() and this.notify(). However, thread1 and thread2 are separate objects so they are not ever going to communicate via this method.
In order for communication to occur, you need a shared lock object. For example:
Object lock = new Object();
firstThread = new firstThread(lock);
secondThread = new secondThread(lock);
and synchronizations like:
void wait(Object lock) {
synchronized(lock) {
lock.wait();
}
}
void notify(Object lock) {
synchronized(lock) {
lock.notify();
}
}
Disclaimer: I would never do this personally, however it does answer the OP's question.
This code is really confusing, which is making it hard to see the underlying problem.
You should never start a class with a lower-case letter since it makes it look like a method/field name (e.g. firstThread).
I'm pretty sure Wait and Notify have no reason to be synchronized.
Why does secondThread inherit from firstThread??? Actually, why do you have those two classes at all? You should just make an anonymous inner class from Helper1 or something.
Anyway, the problem is that when you call Notify() in thread1 it notifies itself, not thread2.
I have implemented a Steaming API for twitter. I get the streams perfectly. However, My program never ends. I have tried many combinations but can't figure out why. I am suing Apache AsyncHttpClient in java. My goal is to start the stream for example for 10 seconds, get the streams, and gracefully close the stream and exit the application (I am expecting this to happen when my Main method ends naturally). This is the code below:
public static void main(String[] args) throws Exception
{
TwitterStreamingHttpClient client = new TwitterStreamingHttpClient();
Executor ex = Executors.newSingleThreadExecutor();
ex.execute(client);
Thread.sleep(5000);
client.ceaseStream();
LOG.debug("Keeps running");
}
and this:
public class TwitterStreamingHttpClient extends DefaultHttpAsyncClient implements Runnable
{
private final static Logger LOG = LoggerFactory.getLogger(TwitterStreamingHttpClient.class);
/**
* #throws IOReactorException
*/
public TwitterStreamingHttpClient() throws IOReactorException
{
super();
// TODO: parametrize it, load from config file, spring config file?
this.getCredentialsProvider().setCredentials(new AuthScope("stream.twitter.com", 80),
new UsernamePasswordCredentials("username", "password"));
this.start();
}
public void initiateStream() throws UnsupportedEncodingException, InterruptedException, ExecutionException
{
String requestContent = new String();
requestContent = "track=NothingFeelsBetterThan";
Future future = this.execute(HttpAsyncMethods.createPost(
"https://stream.twitter.com/1.1/statuses/filter.json", requestContent,
ContentType.APPLICATION_FORM_URLENCODED), new TwitConsumer(), null);
Boolean result = future.get();
if(result==null)
{
LOG.error("Requested to close stream!");
return;
}
}
public void ceaseStream()
{
try
{
this.shutdown();
LOG.info("Shutting down the stream");
}
catch (InterruptedException e)
{
LOG.debug("InterruptedException {}", e);
}
}
/*
* (non-Javadoc)
*
* #see java.lang.Runnable#run()
*/
public void run()
{
Thread.currentThread().setName("initiateSTream Thread");
try
{
initiateStream();
Thread.currentThread().interrupt();
}
catch (UnsupportedEncodingException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (ExecutionException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I tried to add a return whereever I though it mightbe helpful. but no luck. Can someone help me with this?
Edit 1: When I use the debug mode, I can see that the "initiateSTream Thread" thread. is still running while the main thread is gone!
Edit 2 (Solution): In the main method, I replaced:
Executor ex = Executors.newSingleThreadExecutor();
ex.execute(client);
with:
Thread thread = new Thread(client);
thread.start();
Now my programs ends after the designated time of streaming. But why? What is the difference between the two approaches?!