Search code examples
javamultithreadingtimerrunnable

have method return false if a block of code is taking to long


Having trouble with threads and timers. I need this method to execute some code but if the code takes to long the method should return false. Here is what I am doing:

    public boolean handShake() {

        java.util.Timer t = new java.util.Timer();
    t.schedule(new java.util.TimerTask() {
            public void run() {
                if (threadSuccess = false) {
                    System.out.println("will kill");
//not sure but this is how I read you should kill threads?
                    Thread t = handShakeThread;
                    handShakeThread = null;
                    t.interrupt();
                    System.out.println("Should have killed thread");
                }
            }
        }, 8000);

        try {
            System.out.println("Going to start threads");

            handShakeThread = new Thread(new HandShakeThread());
//handShakeThread is a field (Threat) and HandShakeThread is a class extending Runnable
            handShakeThread.start();
        System.out.println("Thread started");
            handShakeThread.join();
            System.out.println("finished");
            return threadSuccess;
        } catch (InterruptedException e1) {
            e1.printStackTrace();
            return false;
        }
    }

The timer task never appears to be called. It sits there waiting and waiting. What can I do?

Extra info: The handShakeThread is reading from a network. If it completes the reading successfully, field threadSuccess is set to true. The idea is that if reading from the network is taking to long, there should be a time out. Is this the best way of doing this?


Solution

  • Try re-writing your HandShakeThread as a Runnable and doing something like this. If the Runnable does not complete after 8 seconds, the method will return false.

    public boolean handShake() {
        Runnable handShakeTask = new Runnable() {
            @Override
            public void run() {
                // do network stuff
            }
        };
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        try {
            Future<Boolean> future = executorService.submit(networkTask, true);
            executorService.shutdown();
            return future.get(8, TimeUnit.SECONDS);
        } catch (TimeoutException ex) {
            return false;
        } catch (InterruptedException | ExecutionException e) {
            // handle exception
        } 
    }