I have the following logic (simplified):
public class Application {
public static volatile boolean stopServer;
private static ScheduledExecutorService taskScheduler;
private static Thread listenerThread;
public static synchronized void switchStopServer() {
stopServer = true;
listenerThread.interrupt();
taskScheduler.shutdownNow();
}
public static void main(String[] args) {
int threadPoolSize = 4;
taskScheduler = Executors.newScheduledThreadPool(threadPoolSize);
listenerThread = new ListenerThread();
taskScheduler.schedule(listenerThread, 0, TimeUnit.NANOSECONDS);
}
}
public class ListenerThread extends Thread {
private static ServerSocket serverSocket;
private Socket socketConnection;
#Override
public void run() {
while (!Application.stopServer) {
try {
socketConnection = serverSocket.accept();
new CommunicatorThread(socketConnection).start();
} catch (SocketException e) {
} catch (Exception e) {
}
}
}
private static void closeServerSocket() {
try {
if (serverSocket != null && !serverSocket.isClosed()) serverSocket.close();
} catch (Exception e) { }
}
#Override
public void interrupt() {
closeServerSocket();
super.interrupt();
}
}
What I want to achieve, is to terminate Threads the proper way. First of all, is this (switchStopServer()) the correct way to do that, or are there any better solutions?
I'm a little confused with the ScheduledExecutorService, because shutdownNow() does not interrupt the Threads, neither does ScheduledFuture.cancel(true) (at least for me it doesn't), so I can't interrupt ServerSocket.accept(). I know, in my example there is no need for the ScheduledExecutorService, but in my real application there is.
Your problem I believe is that you are confusing Thread and Runnable. Even though ListenerThread extends Thread, it is actually not it's own thread. The thread is managed by the ExecutorService thread-pool which is just calling your run() method. This is only [sort of] working because Thread also implements Runnable. When you call ListenerThread.interrupt() you are not interrupting the thread in the thread-pool although you are calling your interrupt() method but just directly in the calling thread. This should close the socket since it calls closeServerSocket() from the outside.
When you call ScheduledFuture.cancel(true) or shutdownNow(), the pool thread(s) should be interrupted but this will not call your interrupt() method there. You can test for the interruption by using Thread.currentThread().isInterrupted() in your run() method.
You should change ListenerThread from extending Thread and instead have it just implement Runnable (see edit below). You will want to do something like the following loop in your run() method:
while (!Application.stopServer && !Thread.currentThread().isInterrupted()) {
To interrupt the accept() method, you are going to have to close the serverSocket from another thread. Most likely this will be done by the thread that is calling interrupt(). It should close the socket, shutdownNow() or cancel() the thread-pool, and then it can wait for the pool to terminate.
Edit:
Actually, I wonder why you are using a pool for your ListenerThread since there will only ever be one of them, it is being scheduled immediately, and it is just starting a new thread on any connection directly. I would remove your taskScheduler pool entirely, keep ListenerThread extending Thread, and just call new ListenerThread().start();.
The outer thread would still just close the serverSocket to stop the ListenerThread. If you also need to close all of the connections as well then the ListenerThread needs to keep a collection of the socketConnection around so it can call close() on them when the accept() throws a n IOException.
Also, currently you have private Socket socketConnection; which is misleading because it will change after every call to accept(). I'd rewrite it as:
Socket socketConnection = serverSocket.accept();
new CommunicatorThread(socketConnection).start();
Related
Suppose I have a class:
public final class Server {
private final ArrayList<ServerConnection> connections;
private ServerConnection pending;
private Thread connector;
public Server() {
connections = new ArrayList<>();
connector = new Thread(() -> {
while (true) {
pending = new ServerConnection();
pending.waitForConnection();
//Could be adding while another thread is iterating.
connections.add(pending);
}
}, "Connection Establisher");
connector.setDaemon(true);
connector.setPriority(Thread.MIN_PRIORITY);
connector.start();
}
//Anyone with a refrence to this object can access connections.
public ArrayList<ServerConnection> getConnections() {
return connections;
}
}
How would I make sure that connections is not in use while I add an object. I thought about using a synchronized (connections) {...} block in the thread but from my knowledge of synchronized blocks all non-thread-safe references to connections would have to be in a synchronized block. Is there some way that I can make sure that all non-thread-safe access to connections are synchronized?
Making the getConnections method synchronized is not enough because once the caller gets a reference to the list, it can do whatever it wants with it, including thread unsafe operations.
A few simple steps would make your code more robust:
only use final variables
provide a start and stop method. At the moment you start the thread in the constructor and leak a reference to this - this could have weird visibility effects. And you don't manage the thread stopping, making the thread a daemon instead - it works but is probably not as clean.
A simple rewrite could look like the code below (it can certainly be improved) - check the comments. Note that it would work better if the waitForConnection reacted to interruption appropriately too, for example by throwing an InterruptedException.
public final class Server {
//us a thread safe list
private final List<ServerConnection> connections = new CopyOnWriteArrayList<>();
//make the thread final
private final Thread connector;
public Server() {
connector = new Thread(() -> {
//provide a mechanism to stop the thread: exit on interruption
while (!Thread.currentThread().isInterrupted()) {
ServerConnection pending = new ServerConnection();
pending.waitForConnection();
//Could be adding while another thread is iterating.
connections.add(pending);
}
}, "Connection Established");
//Note that the priority may be ignored at runtime
connector.setPriority(Thread.MIN_PRIORITY);
}
public void start() {
connector.start();
}
//to stop the thread, interrupt it
public void stop() {
if (!connector.isAlive()) throw new IllegalStateException("The server is not started");
connector.interrupt();
}
//don't return the list but an unmodifiable view of the list
public List<ServerConnection> getConnections() {
return Collections.unmodifiableList(connections);
}
}
My code:
public class EventHandler implements Runnable, SomeEventListener {
private static final EventHandler INSTANCE = new EventHandler();
private static final Thread THREAD = new Thread(INSTANCE);
private static volatile boolean isRunning = false;
private EventHandler () {}
private static EventHandler getInstance() {
return INSTANCE;
}
public void start() {
isRunning = true;
THREAD.start();
}
public void stop() {
isRunning = false;
}
//Listener method that was overriden
public void onEvent(Event event) {
//...do stuff
}
#Override
public void run() {
//Do nothing, let the listener do its job
while (isRunning) {
try {
logger.info("Sleeping...");
Thread.sleep(5000);
logger.info("Done sleeping...");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Basically the run() method does nothing - just sleeps every 5 seconds, wakes up, sleeps again. What I don't understand is when it's asleep, this EventHandler class still gets events. How does this happen? Shouldn't the class stop receiving events since the thread is asleep?
The thread and the class are two different things. EventHandler is an object that has a dedicated thread executing its run method. At the same time it has its onEvent method which is available to get called by other threads.
Log the thread ID in the onEvent method and in the run method to confirm the sleeping thread is not involved in receiving events.
Classes don't own threads. Your THREAD is spinning doing its sleeping, logging, and flag-checking, while other threads in your program call onEvent. (Also the OS-level thread is a separate thing from the object whose reference you saved as THREAD.)
You could use a thread pool and that would keep your application alive until you shut it down. It would be better to submit Runnables to a thread pool than to give each Runnable its own dedicated thread.
That thread seems really useless. I don't know how you think Listeners work, but basically they are just references that some thread you probably never saw will use to call certain methods if they see something happen.
A listener does not just "catch" any events thrown into the room.
Like I said: This thread seems useless because it doesn't do anything. At all. The Events are called from a different thread. You don't need this one for it.
I have a thread pool on the function that the clients calling.. to make only (n) clients execute this function upload() and the others wait.. i tried to call sleep() in the implementation of the function but it didn't work ...
note: I'm doing this to have time to see that other clients doesn't execute the function while there are (n) clients execute it...
i need fast help please ..
the code of Server:
public class Server extends UnicastRemoteObject implements ExcutorInterface
{
public Server()throws RemoteException
{
System.out.println("Server is in listening mode");
}
public static void main(String arg[]) throws InterruptedException
{
try{
LocateRegistry.createRegistry(1234);
Server p=new Server();
Naming.bind("//127.0.0.1:1234/obj",p);
}catch(Exception e)
{
System.out.println("Exception occurred : "+e.getMessage());
}
}
#Override
public void executeJob() throws RemoteException {
System.out.println("Inside executeJob...");
doJob a=new doJob("req_id","usrname","pwd");
ExecutorService threadExecutor = Executors.newFixedThreadPool(2);
threadExecutor.execute(a);
threadExecutor.shutdown();
}
}
the code of doJob :
public class doJob implements Runnable {
String request_id="", usrnamee="", pswd="";
public static int i = 1;
public doJob(String request_id,String usrnamee,String pswd) {
this.request_id=request_id;
this.usrnamee=usrnamee;
this.pswd=pswd;
}
public void upload() throws InterruptedException, IOException {
Thread.sleep(1000*15);
}
public void run() {
upload();
}
}
and I call executeJob(); in the client
One suggestion is to make "threadExecutor" a static member variable of
server.
If you want only n clients then make the pool have n threads
ExecutorService threadExecutor = Executors.newFixedThreadPool(n);
Shutting down within execute method id does not seem right.
The pool should be shutdown only when you decide to shutdown the
server.
Till then it should be alive and process the client requests.
So you have to remove the shutdown and newFixedThreadPool statements
out of the executeJob method.
To elaborate on my comment, you should surround the Thread.sleep in a try/catch and make sure the thread sleeps as long as you wish it to do so. It would look something like this:
long wakeTime = new Date().getTime() + (1000 * 15);
while ((new Date()).getTime() < wakeTime) {
try {
Thread.sleep(1000*15);
} catch (InterruptedException e) {
// do nothing
}
}
I suspect your thread was waking early because of a signal perhaps because of your call to threadExecutor.shutdown() immediately after threadExecutor.execute(a). You might want to consider calling threadExecutor.awaitTermination() as well.
Edits after learning that the task never executes:
Because threadExecutor.shutdown() doesn't wait for the tasks to complete, it looks like your program is immediately exiting. You should try using threadExecutor.awaitTermination() after your call to threadExecutor.shutdown(), placing it in a loop similar to the one suggested for Thread.sleep().
Get rid of the thread pool and use a counting semaphore to control inline execution of the upload.
I hope Thread.sleep() will help you to resolve.
Also you can use wait().
I have created class by implementing runnable interface and then created many threads(nearly 10) in some other class of my project.How to stop some of those threads?
The simplest way is to interrupt() it, which will cause Thread.currentThread().isInterrupted() to return true, and may also throw an InterruptedException under certain circumstances where the Thread is waiting, for example Thread.sleep(), otherThread.join(), object.wait() etc.
Inside the run() method you would need catch that exception and/or regularly check the Thread.currentThread().isInterrupted() value and do something (for example, break out).
Note: Although Thread.interrupted() seems the same as isInterrupted(), it has a nasty side effect: Calling interrupted() clears the interrupted flag, whereas calling isInterrupted() does not.
Other non-interrupting methods involve the use of "stop" (volatile) flags that the running Thread monitors.
How to stop a thread created by implementing runnable interface?
There are many ways that you can stop a thread but all of them take specific code to do so. A typical way to stop a thread is to have a volatile boolean shutdown field that the thread checks every so often:
// set this to true to stop the thread
volatile boolean shutdown = false;
...
public void run() {
while (!shutdown) {
// continue processing
}
}
You can also interrupt the thread which causes sleep(), wait(), and some other methods to throw InterruptedException. You also should test for the thread interrupt flag with something like:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// continue processing
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// good practice
Thread.currentThread().interrupt();
return;
}
}
}
Note that that interrupting a thread with interrupt() will not necessarily cause it to throw an exception immediately. Only if you are in a method that is interruptible will the InterruptedException be thrown.
If you want to add a shutdown() method to your class which implements Runnable, you should define your own class like:
public class MyRunnable implements Runnable {
private volatile boolean shutdown;
public void run() {
while (!shutdown) {
...
}
}
public void shutdown() {
shutdown = true;
}
}
Stopping the thread in midway using Thread.stop() is not a good practice. More appropriate way is to make the thread return programmatically. Let the Runnable object use a shared variable in the run() method. Whenever you want the thread to stop, use that variable as a flag.
EDIT: Sample code
class MyThread implements Runnable{
private volatile Boolean stop = false;
public void run(){
while(!stop){
//some business logic
}
}
public Boolean getStop() {
return stop;
}
public void setStop(Boolean stop) {
this.stop = stop;
}
}
public class TestStop {
public static void main(String[] args){
MyThread myThread = new MyThread();
Thread th = new Thread(myThread);
th.start();
//Some logic goes there to decide whether to
//stop the thread or not.
//This will compell the thread to stop
myThread.setStop(true);
}
}
If you use ThreadPoolExecutor, and you use submit() method, it will give you a Future back. You can call cancel() on the returned Future to stop your Runnable task.
Stopping (Killing) a thread mid-way is not recommended. The API is actually deprecated.
However, you can get more details including workarounds here: How do you kill a Thread in Java?
Thread.currentThread().isInterrupted() is superbly working. but this
code is only pause the timer.
This code is stop and reset the thread timer.
h1 is handler name.
This code is add on inside your button click listener.
w_h =minutes w_m =milli sec i=counter
i=0;
w_h = 0;
w_m = 0;
textView.setText(String.format("%02d", w_h) + ":" + String.format("%02d", w_m));
hl.removeCallbacksAndMessages(null);
Thread.currentThread().isInterrupted();
}
});
}`
I have an ExecutorService that processes some tasks. The client threads can call shutdown() on the ExecutorService. I want to run some cleanup code after the ExecutorService has completely shutdown. Is there a mechanism to run a callback method after the ExecutorService has completed its shutdown.
NOTE:
I cannot call shutdownNow()
The clean-up code must run after the shutdown() is completed.
The ExecutorService is a newCachedThreadPoolExecutor();
Start another thread/executor-managed-runnable that checks ExecutorService.awaitTermination(...) in a try-catch statement in a loop until it returns true, then run your shutdown handling code. The loop is necessary because the method might return prematurely when interrupted.
Something like this:
public class ShutdownHandler implements Runnable {
private final ExecutorService service;
public ShutdownHandler(final ExecutorService service) {
this.service = service;
}
#Override
public void run() {
boolean terminated = false;
while (!terminated) {
try {
terminated = service.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (final InterruptedException ex) {
// check again until terminated
}
}
// your shutdown handling code here
}
}
I would extends and override:
public class MyExecutorService extends ThreadPoolExecutor {
#Override
public void shutdown() {
super.shutdown();
// do what you need to do here
}
}
Something like that
Well, if you call executorService.invokeAll(myListOfCallableTasks) and them executorService.shutDown() the thread calling that will block until all the tasks are finished:
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html#invokeAll(java.util.Collection)