1

Is there any way to create sleeping thread or process in Java, which get started on some event?

I'm new to Multithreading , I want to create a process or thread which will be in sleep mode and that should get activated only on some change.

Ex. If I add any file in some directory or if I do some changes in file then only my sleeping thread or process should get on automatically. Best example is tomcat, which reload application context by its own.

davioooh
  • 23,742
  • 39
  • 159
  • 250
  • 3
    The answer is Object.wait/notify/notifyAll I was looking for a good tutorial to post for you but couldn't find one. Search the internet and look for more information on these methods – ControlAltDel Feb 28 '17 at 16:04
  • After creation, a Java thread does not run until its [`start()`](https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#start%28%29) method is called. – JimmyB Feb 28 '17 at 16:04
  • You can check https://punekaramit.wordpress.com/2010/04/27/producer-consumer-using-java-threads-waitnotifyall/ out for Object.wait/notify as mentioned in above comment. – Amit Feb 28 '17 at 16:11

4 Answers4

0

You should look at Executors and ThreadPoolExecutor. Basically, threads within a thread pool are "parked", sleeping, until a task is submitted on the thread pool.

You should also investigate about the possibility of using RxJava. Its Observer / Observable paradigm may fit your needs.

Jerome L
  • 607
  • 5
  • 11
0

Is there any way to create sleeping thread or process in Java, which get started on some event?

Literally? No.

Effectively? Yes.

When you start() a thread, it begins to execute a run() method---presumably, a run() method that you wrote. There is no other way to start a thread.

The run() method gives you (the programmer) total control of the thread. If you want a thread that waits for some event and responds to it, then write a run() method that waits for the event and responds to it. If you want a thread that does the same thing again and again, then write a run() method that loops, doing whatever again and again.

It's that simple.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
0

How to let a Thread wait

You need a Object that the Threads shouldnt use parallel in this case aObj. its indifferent which class aObj is. The first Thread will wait at the aObj.wait() line until another Thread calls aObj.notify().

The run Method in the first Thread:

synchronized(aObj) {
    try {
        //Doing something
        //Wait at the next line
        aObj.wait();
        //Not reached until aObj.notify is called
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

The second Thread

synchronized(aObj) {
    aObj.notify();
}

How to Listen to a File change

First you need a WatcherService and a Path to the Directory in which you want to Listen for file changes. Then you have to register on which Events you want to listen very important is that you add the static import.

  • ENTRY_CREATE - A directory entry is created
  • ENTRY_DELETE – A directory entry is deleted.
  • ENTRY_MODIFY – A directory entry is modified.
  • OVERFLOW – Indicates that events might have been lost or discarded. You do not have to register for the OVERFLOW event to receive it.

For more information look at this site: Watching a Directory for Changes

import static java.nio.file.StandardWatchEventKinds.*;

WatchService watcher = FileSystems.getDefault().newWatchService();
Path dir = Paths.get("C:\\PATHTOYOUR\\DIRECTORY\\");
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

After that you should create a while(true) loop and wait for a event. Take the event with watcher.take() and get a List of the events by calling key.pollEvents(). Iterate through it and you can get the filename and the Event.

while(true){
    WatchKey key = watcher.take();
    //Wait until a events arrives
    List<WatchEvent<?>> events = key.pollEvents();
    
    for(int i = 0; i < events.size(); i++){
        //Get the kind of Event
        WatchEvent.Kind<?> kind = events.get(i).kind();
        
        //Get the filename
        WatchEvent<Path> ev = (WatchEvent<Path>) events.get(i);
        Path filename = ev.context();
         
        //Differentiate between the different events
        if(kind == ENTRY_CREATE){
            
        }else if(kind == ENTRY_DELETE){
            
        }else if(kind == ENTRY_MODIFY){
            
        }else if(kind == OVERFLOW){
            
        }
        
        //Exit the loop if the key is inaccessible
        boolean valid = key.reset();
        if (!valid) {
            break;
        }
    } 
}

Take this two Code Snippets and put them into a Thread and you have your own Thread which is called on a File Event.

Community
  • 1
  • 1
Epig
  • 70
  • 9
-1

You can refer my answer to another question at the link : https://stackoverflow.com/a/42049397/504133

In the answer at the link above, I have implemented a small model where you can have the thread in non active state and when you wish you can get it back in active mode.

I have used an Object to take lock upon. Inside a synchronized block a thread can perform its usual assigned job but in case we wish to get it in non active mode, it can notify others waiting threads if any to get ready for aquiring the lock and then lock it relinquishes the lock and goes to non active waiting state.

Now other thread(s) are awakened and they complete with each other for lock acquisition, who so ever thread wins this acquires the lock, does its work and in case of some event it can do the same what was done by first thread , notify other threads to get awakened to compete for lock acquisition , it relinquishes the lock and goes to wait state.

Community
  • 1
  • 1
nits.kk
  • 5,204
  • 4
  • 33
  • 55