I have a java code like this:
private class Uploader implements Runnable
{
// ...
public void start()
{
t.start();
}
public void run()
{
try {
while(i=in.read())
{
output.write(i); // THIS IS A BLOCKING CALL !!
}
} catch(ProtocolException e) { ... }
catch(IOException e1) { ... }
}
private void restore()
{
...
}
private class Checker implements Runnable
{
// ...
#Override
public void run()
{
// I WANT (IN A PARTICULAR MOMENT) TO THROW AN
// EXCEPTION INTO THE Uploader RUN METHOD FROM HERE,
// IS IT POSSIBLE?
}
}
}
The problem is that i have a blocking write() in the Run() method, so I have added a
new thread that checks whether or not the connection is transmitting: if it's not trasmitting I want to stop the blocking write() using the exception mechanism (throwing an exception to the other thread's run() method from the checker thread).
Is it possible?
EDIT [SOLVED]:
The only way is to brutally close the output stream and to work on the amount of written bits to check whether the connection is transmitting:
private class Uploader implements Runnable
{
private OutputStream output;
private int readedBits;
public void run()
{
try {
while(i=in.read())
{
output.write(i);
readedBits++;
}
} catch(IOException e1)
{
// ENTERS HERE IF RESTORE() IS CALLED
}
}
private void restore()
{
try {
output.close();
} catch (IOException e) {}
// Restore connection ....
}
private int getReadedBits()
{
return this.readedBits;
}
private class Checker implements Runnable
{
// ...
#Override
public void run()
{
while(true)
{
try {
Thread.sleep(timeout);
} catch (InterruptedException e1) {}
if(lastReaded >= getReadedBits())
restore();
else
lastReaded = getReadedBits();
}
}
}
}
You can make your code honor Thread.interrupt() call. See javadoc of this call.
Not exactly what you've asked for but I'd rather use java.nio and
public abstract int select(long timeout) throws IOException
to (not only) detect timeouts.
In general with blocking on I/O the only way to move on is to close the resource. As #VolkerK says, the other approach is to use non-blocking I/O, which is more difficult.
I recommend using Interrupts for this. Checker may call interrupt on Uploader class.
E.g.
private class Checker implements Runnable
{
// ...
Uploader uploader;
public Checker(Uploader uploader) {
this.uploader = uploader;
}
#Override
public void run()
{
// CHECK
if(failed) uploader.interrupt();
}
}
Documentation is here: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Related
I have a method in which I call another method that has a callback. I want to receive this callback before leaving my method. I saw some other posts in which latches are used. My code looks like this:
public void requestSecurityToken(<some params>){
final CountDownLatch latch = new CountDownLatch(1);
MyFunction.execute(<someParams>, new RequestListener<Login>() {
#Override
public void onRequestFailure(SpiceException spiceException) {
//TODO
}
#Override
public void onRequestSuccess(Login login) {
//handle some other stuff
latch.countDown();
}
});
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
This doesn't work, the method is stuck in the await() function. What happens is that, the method immediately jumps to the await(), and doesn't go into the onRequestSuccess() or onRequestFailure() method again. I guess this is a concurency problem... Any ideas on how to fix this issue?
EDIT: Added the line of code where I create the latch.
When you are doing this
new RequestListener<Login>
You are passing an object to your function , which implements an interface.
That is why those methods are not getting called , those methods are called only when you get the request result (success or failure).
You can do this instead.
MyFunction.execute(<someParams>, new RequestListener<Login>() {
#Override
public void onRequestFailure(SpiceException spiceException) {
someFunction();
}
#Override
public void onRequestSuccess(Login login) {
//handle some other stuff
someFunction();
latch.countDown();
}
});
public void someFunction()[
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
I have 7 threads running in an ExecutorPool that process data and occasionally need data from a listener instance running on another thread. The listener sends a request over a socket to a server and a while later, when the result is returned, the listener will return the data to the worker thread that called it. I want to block the worker thread until the requested data is returned, but I don't want to block the listener from making other requests from the other worker threads. How do I do that?
If one thread hands off work to another thread, and then subsequently simply waits for the result, you don't need another thread to do the work. You may need a class that does the work, but which is called on the same thread. And if the same instance is used by multiple threads some synchronization may be needed. But the bottom line is this :
You don't need the listener thread. Replace it with a component that handles a request, and call it synchronously.
Edit
Given your own answer, your problem is a bit clearer. As #JimN suggests you probably want to hand out a Future to the worker thread, and make it a CompletableFuture the Listener keeps in a Map keyed by request id until the response returns.
Sample code :
public class WorkUnitProcessor implements Runnable {
// ...
#Override
public void run() {
while(true) {
WorkUnit work = master.getNextWorkUnit();
if(work == null) return;
doWork(work);
}
}
public void doWork(WorkUnit work) {
//Do some work...
try {
DataRequest dataRequest = createRequest(work);
Future<Response> future = server.getData(dataRequest);
Response response = future.get(); // this call blocks until the Response is available.
//finish doing work
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
// handle e.getCause()
}
}
// ...
}
public class Server implements DataSourceDrivenCallback {
private final DataSource dataSource;
private Map<Integer, CompletableFuture<Response>> openRequests = new ConcurrentHashMap<>();
public Server(DataSource dataSource) {
this.dataSource = dataSource;
}
#Override
public void incomingDataCallback(int requestId, ChunkOfData requestedData) {
CompletableFuture<Response> responseHolder = openRequests.remove(requestId); // get the responseHolder
if (responseHolder != null) {
responseHolder.complete(toResponse(requestedData)); // make the response available.
}
}
public Future<Response> getData(DataRequest datarequest) {
int requestId = dataSource.submitRequest(serializeAndTranslateRequest(datarequest));
CompletableFuture<Response> future = new CompletableFuture<>();
openRequests.put(requestId, future);
return future;
}
// ...
}
I think this might work. What I was looking for is described here:
https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
It's the ability to make a thread sleep until it is notified by the thread that it is waiting on. Seems easy to use.
public class DataProcessor {
private List<WorkUnit> work;
private Server server;
public DataProcessor(List<WorkUnit> work, int numprocessors) {
this.work = work;
setupProcessors(numprocessors);
Server server = new Server();
}
private void setupProcessors(int numprocessors) {
for(int i = 0; i < numprocessors; i++) {
WorkUnitProcessor worker = new WorkUnitProcessor(this, server);
worker.start();
}
}
public synchronized WorkUnit getNextWorkUnit() {
if(work.isEmpty()) return null;
return work.remove(0);
}
}
public class WorkUnitProcessor(Server server) {
private DataProcessor master;
private Server server;
public WorkUnitProcessor(DataProcessor master) {
this.master = master;
}
#Override
public void run() {
while(true) {
WorkUnit work = master.getNextWorkUnit();
if(work == null) return;
doWork(work);
}
}
public void doWork(WorkUnit work) {
//Do some work...
server.getData(datarequest, this);
while(!datarequest.filled) {
try {
wait();
} catch (InterruptedException e) {}
}
//finish doing work
}
}
public class Server implements DataSourceDrivenCallback {
private DataSource ds;
private Map<Integer, OpenRequest> openrequests;
public Server() {
//setup socket and establish communication with server through DataSource object
DataSource ds = new DataSource(<ID>, <Socket>);
}
public synchronized void getData(DataRequest datarequest, WorkUnitProcessor workerthread) {
int requestid = ds.submitRequest(serializeAndTranslateRequest(datarequest));
openrequests.add(new OpenRequest(workerthread, datarequest));
}
#Override
public void incomingDataCallback(int requestid, ChunkOfData requesteddata) {
OpenRequest request = openrequests.get(requestid);
request.datarequest.storeData(requesteddata);
request.workerthread.notify();
}
}
public class OpenRequest {
private WorkUnitProcessor workerthread;
private DataRequest datarequest;
//other details about request
}
I have an inner class that extends Thread
private class TestStart extends Thread {
public void run() {
try {
startServer();
}
catch (Exception e) {
/// How to handle it?
}
}
}
The caller in the main thread:
public void start() throws Exception {
Thread st = new TestStart();
st.start();
}
Method startServer() throws Exception by its API, so I have to use try-catch as Thread.run() does not "throws" exception in method definition. I need to bubble up the caught exception into the main thread to handle it. Is there an easy way to do it? Thanks
If you use an ExecutorService instead of using raw threads, you can be notified of uncaught exceptions:
class MyCallable implements Callable<Void> {
#Override public Void call() throws Exception {
// Do something - you don't need to catch Exception as Callable throws it.
// ...
return null; // A return is necessary from a Callable.
}
}
Create an executor service somewhere, e.g.:
ExecutorService executor = Executors.newFixedThreadPool(1);
Then, in the code where you start the thread:
Future<?> future = executor.submit(new MyCallable());
try {
future.get(); // Blocks until the Callable completes.
} catch (ExecutionException e) {
// You reach here if an exception is thrown in the Callable -
// The exception is accessible via e.getCause().
}
Set a new exception handler on your Thread.
st.setDefaultUncaughtExceptionHandler(new Thread.
UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t + " throws exception: " + e);
}
});
And place that code before your start();
There is a few possible solutions. For example:
Use setUncaughtExceptionHandler()/setDefaultUncaughtExceptionHandler() and change your try/catch
try {
startServer();
}
catch (RuntimeException e) {
throw e;
}
catch (Exception e) {
throw new RuntimeException(e);
}
Or use your custom listener
private class TestStart extends Thread {
private final ServerStateListener lnr;
TestStart(ServerStateListener lnr) {
this.lnr = lnr;
}
public void run() {
try {
startServer();
lnr.onServerStarted();
}
catch (Exception e) {
lnr.onServerStoppedByError(e);
}
}
}
Or just save Exception and read it after .join
private class TestStart extends Thread {
private Exception error; // if you start and join and read this property within one thread, you don't need to use volatile, otherwise do it for safe publication
public void run() {
try {
startServer();
}
catch (Exception e) {
error = e;
}
}
public Exception getError() {
return error;
}
}
Or use ExecutorService/Callable instead of your own thread as Andy suggested.
I am working with network so I have to use new thread.These my methods in SmackClass:
public void login(String username,String password) throws XMPPException, SmackException, IOException {
ConnectionConfiguration configuration=new ConnectionConfiguration("", 5222,"localhost");
configuration.setSecurityMode(SecurityMode.disabled);
connection=new XMPPTCPConnection(configuration);
connection.connect();
connection.login(username,password);
chatManager = ChatManager.getInstanceFor(connection);
chatManager.addChatListener(new ChatManagerListener() {
public void chatCreated(final Chat chat, final boolean createdLocally) {
chat.addMessageListener(messageListener);
}
});
}
public void sendMessage(String to,String message) throws NotConnectedException, XMPPException {
Chat chat=chatManager.createChat(to,messageListener);
chat.sendMessage(message);
}
I am calling above methods like this(in main class):
final SmackClass smack=new SmackClass();
Thread thread=new Thread() {
#Override
public void run() {
try {
smack.login("android","test");
} catch (XMPPException | SmackException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
thread.start();
try {
smack.sendMessage("pidgin#localhost", "test");
} catch (NotConnectedException | XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
My application is giving nullPointerException for smack.sendMessage line because I am setting chatManager variable inside login method and this method is running in another thread.I know if I put smack.sendMessage line to inside this thread it will work.But I don't want to do this.Because I will use sendMessage method in another main class method.How can I resolve this problem ? I guess I need to do all network operations in single thread (not ui thread) but how ?
Easiest way is to implement a Queue. NetworkThread always look at queue if anything to process. Chat UI thread can put the command in to queue.
public class NetworkThread implements Runnable {
Queue<Command> queue;
public NetworkThread(Queue<Command> queue) throws IOException {
this.queue = queue;
}
public void run() {
while (true) {
Command command = queue.poll()
if(command != null){
command.execute();
}
}
}
}
Command is a interface you can define to implement each network operation.
interface Command{
public void execute();
}
class LoginCommand implements Command{
public void execute(){
//Do login operation
}
}
Now UI thread can push a Command Object in to queue, network thread will take care of executing it. Yo u may need to implement a message return mechanism in reverse direction as well.
I'm trying to implement a piece of code to synchronously start looped service in Java. The idea is, code under // STARTER comment should be considered as piece of Service.go() method, so if service fails to start, I want to re-throw the exception synchronously. That piece of code should only finish in case I've tried to start the thread, waited until its execution flow reached some point and next, if there are no problems, my go() method quits and thread goes on, or, if there were problems, I can re-throw the exception caught in thread's run() method from my go() method. Here's the solution that seems to work fine, but I'm curious if it's possible to make it a couple times shorter :-)
public class Program {
private static boolean started;
private static Throwable throwable;
public static void main(String[] args) {
final Object startedSetterLock = new Object();
Thread thread = new Thread() {
public void run() {
System.out.printf("trying to start...\n");
boolean ok;
Throwable t = null;
try {
init();
ok = true;
} catch(Exception e) {
ok = false;
t = e;
}
synchronized(startedSetterLock) {
started = ok;
throwable = t;
startedSetterLock.notifyAll();
}
if(!ok) {
return;
}
while(true) {
try {
System.out.printf("working...\n");
Thread.sleep(1000);
} catch(InterruptedException e) {
System.out.printf("interrupted\n");
}
}
}
private void init() throws Exception { throw new Exception(); } // may throw
};
// STARTER
synchronized(startedSetterLock) {
thread.start();
try {
startedSetterLock.wait();
} catch(InterruptedException e) {
System.out.printf("interrupted\n");
}
}
// here I'm 100% sure that service has either started or failed to start
System.out.printf("service started: %b\n", started);
if(!started) {
throwable.printStackTrace();
}
}
}
And also, there's a reason to have initialization code executed within that thread, so, please, don't advise running initialization code explicitly in go() method and then just passing all the stuff to the thread.
Thanks!
How about overriding the Thread.start() method?
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
while (true) {
try {
System.out.printf("working...\n");
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.printf("interrupted\n");
}
}
}
#Override
public synchronized void start() {
try {
init();
} catch (Exception e) {
throw new RuntimeException(e);
}
super.start();
}
private void init() throws Exception {
throw new Exception("test");
}
};
t.start();
}