This discussion is archived
14 Replies Latest reply: Nov 5, 2008 1:38 PM by 807589 RSS

How to get thread B to tell thread A to execute a method?

807589 Newbie
Currently Being Moderated
Hey everyone,

My program is comprised of the main thread and a timer thread. How do I get the timer thread to tell the main thread to execute a certain method?
  • 1. Re: How to get thread B to tell thread A to execute a method?
    DrClap Expert
    Currently Being Moderated
    mainThread.certainMethod();
    Of course that presupposes that your timer thread has a reference to the main thread. But that's very simple to arrange.
  • 2. Re: How to get thread B to tell thread A to execute a method?
    807589 Newbie
    Currently Being Moderated
    I'd argue that it's better to think of the objects that happen to have threads associated with them, rather than threads that happen to have objects associated with them.

    And that the way you'd do this would be to have a method on the target object that would add an instruction to a queue. Then arrange it so that the thread associated with that object periodically checked the queue. Access to that queue would have to be synchronized, because the former method would be called by a different thread than the latter.

    But I'm not an expert in these things; perhaps someone has a different opinion. Also, one of the new concurrency utilities may help.
  • 3. Re: How to get thread B to tell thread A to execute a method?
    807589 Newbie
    Currently Being Moderated
    wait...wuh?
    public class GameBox
    {
       public void someMethod()
       {
          ...
       }
    
       public static void main(String[] args)
       {
          ...   
          Thread mainThread=Thread.currentThread()
          Timer t=new Timer(mainThread);
          t.start();
          ...
       }
    }
    
    public class Timer extends JLabel implements Runnable
    {
       private Thread mainThread;   
    
       public Timer(Thread thread)
       {
          this.mainThread=thread;
       }
       
       public void run()
       {
          ...
          mainThread.someMethod();
          ...
       }  
    
       public void start()
       {
          (new Thread(this)).start();
       }
    }
    is this what you mean? cuz it doesn't work...
  • 4. Re: How to get thread B to tell thread A to execute a method?
    DrClap Expert
    Currently Being Moderated
    sci_guy89 wrote:
    it doesn't work...
    You might want to elaborate on that a little bit, don't you think?
  • 5. Re: How to get thread B to tell thread A to execute a method?
    807589 Newbie
    Currently Being Moderated
    lol sorry...i get an error which says the method is undefined for type Thread
  • 6. Re: How to get thread B to tell thread A to execute a method?
    DrClap Expert
    Currently Being Moderated
    Well, that's true. The someMethod() you want to call is a method of the Gamebox class. So you need a reference to a Gamebox object.
  • 7. Re: How to get thread B to tell thread A to execute a method?
    807589 Newbie
    Currently Being Moderated
    And in my code, I did do that.

    Here's the problem:

    In my timer thread, I do...
     GameBox.someMethod(); 
    ... which works absolutely fine except that the code is now being run in my TIMER thread.

    I don't want that.

    I want my timer thread to tell the MAIN thread to invoke the method, but I don't know how.
  • 8. Re: How to get thread B to tell thread A to execute a method?
    DrClap Expert
    Currently Being Moderated
    Why do you care which thread is running when the method is executed?
  • 9. Re: How to get thread B to tell thread A to execute a method?
    807589 Newbie
    Currently Being Moderated
    Because...lol...I don't noe how else to implement this thing i am doing.
    So there's no way for one thread to "talk" to another thread?

    OK...here's a concrete example:

    Thread A is continuously printing java to the console via printJava();
    "At the same time" Thread B starts counting from 0. Once thread B reaches 10, I want thread A to start printing c++ via printCpp();
    When thread B reaches 20, thread A starts printing python via printPython();

    get it...?

    How do I get thread B to communicate with thread A????

    Ugh, programming's such a b*tch sometimes.
  • 10. Re: How to get thread B to tell thread A to execute a method?
    807589 Newbie
    Currently Being Moderated
    Threads can communicate using shared objects. Suppose two threads had references to the same instance of OutputLanguage:
    class OutputLanguage {
        public enum Language {JAVA, CPP, PYTHON};
    
        public volatile Language current;
    }
    One thread could change the current language to CPP. The other thread could check and see what the current language is and react to this.
  • 11. Re: How to get thread B to tell thread A to execute a method?
    807589 Newbie
    Currently Being Moderated
    It is simple.When u instantiate a thread pass the calling object in the constructor.Then save this object in thread b as a field.Then u can call the functions of the calling thread by using the object passed.However this will not work from a static point of view.So I suggest the following
    public class GameBox
    {
    public GameBox()
    {      ...
    Timer t=new Timer(this);
    t.start();
    }

    public void someMethod()
    {

    }

    public static void main(String[] args)
    {
    ...
    GameBox game =new GameBox();
    game.someMethod();
    ...
    }
    }

    public class Timer extends JLabel implements Runnable
    {
    private GameBox game;

    public Timer(GameBox game)
    {
    this.game=game;
    }

    public void run()
    {
    ...
    game.someMethod();
    ...
    }


    }
  • 12. Re: How to get thread B to tell thread A to execute a method?
    807589 Newbie
    Currently Being Moderated
    DrLaszloJamf wrote:
    Threads can communicate using shared objects. Suppose two threads had references to the same instance of OutputLanguage:
    AtomicReference is available for the purpose of sharing a reference between threads, eg:
    import java.util.concurrent.atomic.AtomicReference;
    
    public class LanguagePrinter {
        enum Language { JAVA, CPP, PYTHON };
    
        public static void main (String...args) {
            final AtomicReference<Language> languageToPrint =
                    new AtomicReference<Language>(Language.JAVA);
    
            new Thread(new Runnable () {
                @Override
                public void run () {
                    for (;;) {
                        Language language = languageToPrint.get();
    
                        if (language == null) return;
    
                        switch (language) {
                            case JAVA:   System.out.println("Java"); break;
                            case CPP:    System.out.println("C++"); break;
                            case PYTHON: System.out.println("python"); break;
                        }
    
                        sleep(300);
                    }
                }
            }, "Thread A").start();
    
            new Thread(new Runnable () {
                @Override
                public void run () {
                    for (Language language : Language.values()) {
                        languageToPrint.set(language);
    
                        for (int i = 0; i < 10; ++i) {
                            System.out.println("i : " + i);
                            sleep(400);
                        }
                    }
    
                    languageToPrint.set(null); // done
                }
            }, "Thread B").start();
        }
    
        static void sleep (long time) {
            try {
                Thread.sleep(time);
            } catch (InterruptedException ex) {
                throw new RuntimeException(ex);
            }
        }
    }
    But there are as many patterns as there are uses for them; whether you want a queue of events or poll for a change or notify, whether you want the server thread which is doing the executing to have a big switch or pass in an object which performs arbitrary functions, such as a Runnable, that is then executed. So you may be better off using one of the existing executors from the java.util.concurrent package rather than writing your own, and passing it Callable objects to do.
  • 13. Re: How to get thread B to tell thread A to execute a method?
    807589 Newbie
    Currently Being Moderated
    ok u can do one thing in Thread B u mention if condition in which u sud write
    if(i==10) {
       try{
         Thread.sleep(1000);
      }catch(InterruptedException ie){
        System.out.println(""+ie);
       }
    if(i==20){
      try{
         Thread.sleep(1000);
      }catch(InterruptedException ie){
        System.out.println(""+ie);
       }
    }
    }
      
    and till that Thread A sud be run after mention Thread.yield(); inside Thread A.

    Edited by: Modi on Nov 7, 2008 2:48 AM
  • 14. Re: How to get thread B to tell thread A to execute a method?
    807589 Newbie
    Currently Being Moderated
    sci_guy89 wrote:
    And in my code, I did do that.

    Here's the problem:

    In my timer thread, I do...
     GameBox.someMethod(); 
    ... which works absolutely fine except that the code is now being run in my TIMER thread.

    I don't want that.

    I want my timer thread to tell the MAIN thread to invoke the method, but I don't know how.
    We're polite to other threads these days. We don't tell them to do stuff, we ask them.

    So in a case like this your main thread asks "what should I do now?" at some point and the timer thread updates the field with the answer to that question.

    The exact nature of that field can be one of lots of possibilities. It could, for example be an enumerated value or a reference to an interface which defines the signature of the method to be called. Whatever suits your application. If it's "atomic" i.e. a single word like a reference you shouldn't have any real problems with thread safety. If it's more complex then you'll need to use synchronized blocks to protect access.

    What you can't do is simply "butt in" on what another thread happens to be doing and make it do something else instead. That stuff is all depracated because it leads to subtle, random bugs.

    You can throw an interrupt at another thread, but that only has immediate effect if the thread is sleeping or waiting.