Results 1 to 10 of 10
  1. #1
    robs is offline Member
    Join Date
    Feb 2011
    Posts
    58
    Rep Power
    0

    Default Correct implementation of EDT

    Hi,

    I am trying to write a two player game. The communication works by sending messages to a server using writeUTF and receiving them using readUTF. I really just want to check that my use of threads is efficient and correct. As there are a lot of different messages and each one invokes another Runnable thread, there are a lot of main$1.class type files in the final build. Sometimes when the game is running, occaionally there is a message in the console which says something like "could not find main$24, try again..." (I will try and find it and provide an exact quote of the message if necessary) and although this doesn't seem to have any effect on the game, it is a little disconcerting. Perhaps I am a little uncomfortable with invokeAndWait... because I am not used to seeing so many new threads all over the place.

    Incoming messages are read on a thread in a loop:

    Java Code:
     public void run() {
         while (true) {
             try {
                 String s = input.readUTF();
                 processMessage( s );
             }catch ( IOException e ) {e.printStackTrace();}
        }
    }
    In processMessage, the messages are interpreted and acted upon as follows:

    Java Code:
       if(s.equals("pass")){//player passed  
           moreInfo = input.readUTF();//receive more info
           moreInt = input.readInt();//receive more info
           try{
               javax.swing.SwingUtilities.invokeAndWait(new Runnable(){
                   public void run(){
                       pass();
                   }
               });
           }catch(Exception e){System.err.println("validchall() err");}
       }
    Would there be any problem with using invokeLater here, in the event that the next piece of code doesn't rely on the code running on the EDT?

    On the other hand, when a button is pressed (invoking a method on the EDT), this is what happens:

    Java Code:
    private void passButtonPressed(){
           moveTypeFP[playerTurn] = "Passed";
           scorePad.paintWindow(playerTurn);
           nextPlayer();
    
           new Thread(){
               @Override
               public void run(){
                    sendServerMessage("pass");
               }
           }.start();
           
           lastScore[myPlayerNo] = 0;
    }
    Is this the correct way of sending the message on another thread? Is there any difference between doing this and using a swingworker (given that I wouldn't be using any of SwingWorker's methods like done()).

    I know there are a lot of questions there, but I think they are all based around one idea.

    Thank you in advance.

    Rob

  2. #2
    doWhile is offline Moderator
    Join Date
    Jul 2010
    Location
    California
    Posts
    1,642
    Rep Power
    7

    Default Re: Correct implementation of EDT

    Rather than spawning all those threads (it is not clear how often they are run), you might consider creating a single thread containing a queue of tasks - perhaps even two threads: one for sending the messages and another for reading and/or parsing the responses. This gives you a good framework to dispatch and receive things in order, as well as (at least in my mind) organizes the workflow more clearly

  3. #3
    robs is offline Member
    Join Date
    Feb 2011
    Posts
    58
    Rep Power
    0

    Default Re: Correct implementation of EDT

    Hi,

    Thanks for your response. That sounds like it makes more sense! So it would look something like this?:

    Java Code:
    public void processMessage(){// Process messages sent by server
        if(message.equals("do something")){
            a = myReadInt();
            b = myReadUTF();
        }
    
        else if(message.equals("do something else")){
            a = myReadInt();
            b = myReadUTF();
        }
    
        String m = message;
        try{
            javax.swing.SwingUtilities.invokeLater(new Runnable(){
                public void run(){
                    processMessageEDT(m);
                }
            });
        }catch(Exception e){System.err.println("error");}
    
    }

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,016
    Rep Power
    20

    Default Re: Correct implementation of EDT

    Something like that, but I would consider making your message processing separate classes.
    Be easier to test (IMO) and, if they have the same interface, should shift all those ifs into a factory method somewhere else.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  5. #5
    robs is offline Member
    Join Date
    Feb 2011
    Posts
    58
    Rep Power
    0

    Default Re: Correct implementation of EDT

    What do you mean by "if they have the same interface" and "factory method"? Please excuse my ignorance.

  6. #6
    robs is offline Member
    Join Date
    Feb 2011
    Posts
    58
    Rep Power
    0

    Default Re: Correct implementation of EDT

    OK, this is where I am at the moment. I haven't moved the original processMessage into its own class because it involves updating a lot of variables from the main class, it seems like a lot of work to move it to another class and then reference all the variables from there. Does anyone have any comments? myMessProc is the instance of the new EDTMessageProcessor class.

    Java Code:
    private void processMessage( String s ) {
        String[] strings = {null, null, null, null, null, null};
        int[] ints = {-1, -1, -1, -1, -1, -1};
    
        if(s.equals( "do something")) {
            ints[0] = dbUpdated();
        }
    
        else if(s.equals( "do something else")) {
            ints[0] = myReadInt();
            ints[1] = myReadInt();
            strings[0] = myReadUTF();
            strings[1] = myReadUTF();
        }
    
        myMessProc.processMessage(s, strings, ints);
    }
    Here is the new class with the EDT code:

    Java Code:
    class EDTMessageProcessor{
        
    Main parent;
    public EDTMessageProcessor(Main m){
        parent = m;
    }
    
    private String message;
    private int[] ints;
    private String[] strings;
    protected void processMessage(String s, String[] ss, int[] is){
        message = s;
        ints = is;
        strings = ss;
        try {
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    String s = message;
                    String[] ss = strings;
                    int[] is = ints;
                    processMessageEDT(s, ss, is);
                }
            });
        } catch (Exception e) {
            System.err.println("procMessEDT did not successfully complete");
        }    
    }
    
    private void processMessageEDT(String mess, String[] strings, int[] ints){
        if(mess.equals( "do something")) {
            parent.createButtons(ints[0]);
            parent.gameTable.fixNewSize(parent.gameTable.width, 
                                    ints[0]*parent.gameTable.ROW_HEIGHT);
        }    
    
        else if(mess.equals( "do something else")) {
            parent.doSomethingElse(ints[0], ints[1]);
            parent.doSomethingElse(strings[0], strings[1]);
        }    
    }
    }
    Last edited by robs; 06-15-2012 at 01:06 PM.

  7. #7
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,016
    Rep Power
    20

    Default Re: Correct implementation of EDT

    A factory method creates an object based on what's supplied.
    Java Code:
    interface SomeInterface {
    ...
    }
    
    class SomeImpl1 implements SomeInterface {
    ...
    }
    class SomeImpl2 implements SomeInterface {
    ...
    }
    class Main {
        public SomeInterface createInterface(...parameters...) {
            if (<some criteria>) {
                return new SomeImpl1(...args...);
            } else {
                return new SomeImpl2(...args...);
            }
        }
    that means you can then simply call, from your code:
    Java Code:
    void processMessage(...parameters...) {
        SomeInterface processor = createInterface(...parameters...);
        processor.doStuff();
    }
    This makes your processing code a lot clearer.
    You get a message then process it.
    The particular implementation handles the specifics.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  8. #8
    robs is offline Member
    Join Date
    Feb 2011
    Posts
    58
    Rep Power
    0

    Default Re: Correct implementation of EDT

    OK, just so I'm clear (I haven't used my own interfaces before, but I think I understand what you are suggesting and the reasons behind it). In this case would someImpl1 be my "do something" and someImpl2 be my "do something else"? So I would have a new class for each message which may be received? And so for my EDT tasks I would have to do the same giving:

    Java Code:
    void processMessage(...parameters...) {
        SomeInterface processor = createInterface(...parameters...);
        processor.doStuff();
        SomeInterface EDTprocessor = createEDTInterface(...parameters...);
        EDTprocessor.doStuff();}

  9. #9
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,016
    Rep Power
    20

    Default Re: Correct implementation of EDT

    No.
    Your processMessageEDT will call the factory method, which will return the processor you need to do the job.
    So you will have just the one processor (at least using the logic in your current processMessageEDT).
    All you're doing is moving the 'if...else if...' into the factory method.

    So that should be the processMessageEDT method. My mistake.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  10. #10
    robs is offline Member
    Join Date
    Feb 2011
    Posts
    58
    Rep Power
    0

    Default Re: Correct implementation of EDT

    Sorry, I'm slightly confused by the correction at the end? Are you saying the factory method (your createInterface()) will replace my processMessageEDT()? What about the things that I don't want to run on the EDT? Something like this?:

    Java Code:
    void processMessage(...parameters...) {
        if(s.equals( "do something")) {
            ints[0] = dbUpdated();
        }
     
        else if(s.equals( "do something else")) {
            ints[0] = myReadInt();
            ints[1] = myReadInt();
            strings[0] = myReadUTF();
            strings[1] = myReadUTF();
        }
    
        SomeInterface EDTprocessor = createEDTInterface(...parameters...);
        EDTprocessor.doStuff();
    }
    Or do you think I should use a factory method for the non-edt code too?

Similar Threads

  1. Please correct this JSP code
    By rajesh4851 in forum New To Java
    Replies: 5
    Last Post: 06-13-2011, 12:12 PM
  2. Please help - can't seem to correct this...
    By jmjbreezin in forum New To Java
    Replies: 7
    Last Post: 05-09-2011, 01:39 PM
  3. Replies: 5
    Last Post: 06-08-2010, 04:22 PM
  4. Is this the correct Output?
    By Teny in forum New To Java
    Replies: 17
    Last Post: 04-13-2009, 12:52 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •