Announcement

Collapse
No announcement yet.

Master/Slave Server

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Master/Slave Server

    Hi,

    ich habe eine Server implementiert, der MATLAB ausführt und Anfragen von Clients über Java weiterleitet und zurückschickt.
    Nun wollte ich, um die Effektivität zu erhöhen auf einen Rechner einen Master Server implementieren der die Anfragen an SlaveServer übergibt, die jewils auf verschiedenen Rechner mit ihrer MATLAB Umgebung laufen.

    Ich habe konkret vier wichtige Klassen:
    • Network: für die Verwaltung, Anfrage Threads werden in einer Queue gepackt
    • NetworkRequestThread: für jede Anfrage wird ein Thread gestartet
    • NetworkSlaveServerStatus: ein Thread der die Slave Server abhört
    • NetworkWorkerThread: der Anfrage-Threads aus der Queue holt und aufruft


    Meine konkrete Frage ist wie kann ich einen Thread aus einer Queue entnehmen und bei diesem bestimmten Thread eine boolean Flrag änder?

    Code:
    public class NetworkWorkerThread implements Runnable{
        
        private Network net;
           
        
        public NetworkWorkerThread(Network net) {
            this.net = net;
        }
        
        public void run() {
            synchronized(this){
                while(net.getSlave1Status()|net.getSlave2Status() == true){
                    net.queueNotifyNext();
                    net.queueRemoveNext(); 
                    //hier müßte der Status des Threads geändert werden, damit der Thread aus NetworkRequestThread arbeiten kann                      
                }
            }
        }
        
    }
    Code:
    public class Network {
    	//...
    	public static Queue q = new LinkedList();
    	private boolean threadStatus = true;
    	
    	public void listen() {
            try {
                serverSkt = new ServerSocket(port);
                alive=true;
                new NetworkSlaveServerStatus(this).startThread();
    			new NetworkWorkerThread(this).startThread();
                
                while(alive){
                    Socket skt = serverSkt.accept();
                    NetworkRequestThread netThread = new NetworkRequestThread(skt,this);
                    q.add(netThread); 
                }           
            }
    
            catch (IOException ex) {
            //...
    		}
        }
    	
    	public void queueNotifyNext() {
            q.iterator().next().notify();
        }
    
        public void queueRemoveNext() {
            q.remove();  
        }
        
        public boolean getStatus() {
          return threadStatus ;
        }
        
        public void pause() {
          threadStatus = true;
        }
     
        public void proceed() {
          threadStatus = false;
          notify();
        }
    }

    Code:
    public class NetworkRequestThread implements Runnable{
    
    //...
    	public void run() {
    	//...
    		synchronized (this){
    			while(net.getStatus()) {
    				try {
    					wait();
    				} catch (InterruptedException ex) {
    					Logger.getLogger(NetworkRequestThread.class.getName()).log(Level.SEVERE, null, ex);
    				}
    			}
    		}
    	}
    	//...
    }

  • #2
    Ein Thread ist eine Klasse wie jede andere auch. Das Flag in dem Thread - was ich jetzt nicht sehe - kann über Getter/Setter gesetzt werden.
    Christian

    Comment


    • #3
      Originally posted by Christian Marquardt View Post
      Ein Thread ist eine Klasse wie jede andere auch. Das Flag in dem Thread - was ich jetzt nicht sehe - kann über Getter/Setter gesetzt werden.
      Ist mir schon klar gewesen, ich habe diese auch implementiert.

      Network:
      Code:
      private boolean threadStatus = true;
      
      public void pause() {
              threadStatus = true;
          }
       
          public void proceed() {
              threadStatus = false;
              notify();
      }

      NetworkWorkerThread:
      Code:
      public class NetworkWorkerThread implements Runnable{
          
          private Network net;
             
          
          public NetworkWorkerThread(Network net) {
              this.net = net;
          }
          
          public void startThread() {
              new Thread(this).start();
          }
          
          public void run() {
              synchronized(this){
                  while(net.getSlave1Status()|net.getSlave2Status() == true){
                      net.queueNotifyNext();
                      net.queueRemoveNext();
                      net.proceed();  //<-----*
                  }
              }
          }
      }
      * An dieser Stelle soll ja, bei dem Thread der Flag geändert werden, der gerade aus der Queue genommen wurde!
      Wie kann man dies mitteilen?

      Comment


      • #4
        Ich verstehe das nicht.

        Das Flag ist nicht im Thread, sondern in einer Klasse, die dem Thread übergeben wird.

        Insofern ist

        Meine konkrete Frage ist wie kann ich einen Thread aus einer Queue entnehmen und bei diesem bestimmten Thread eine boolean Flrag änder?
        unverständlich

        Im Thread kannst du net.proceed und net.pause aufrufen.

        Wenn du von "Network" nur eine instanz hast - wovon ich jetzt ausgehe- kann also jeder Thread diese Methoden aufrufen und den Status ändern. mir ist nun nich klar, wie es ein Status für mehrere Threads geben kann. Das hat dann nichts damit zu tun, dass die Klasse alle Threads in einer Queue verwaltet.

        Davon abgesehen wäre es besser, man verwaltet den Status des Thread in diesem Thread selber.
        Christian

        Comment


        • #5
          Stimmt zuerst hatte ich es auch so gemacht, d.h. in der selben Klasse wird der Status geändert, aber ...

          Wenn man jetzt mehrere Threads hat in denen pause() und proceed() aufgerufen werden kann, wie würde man aus dem WorkerThread proceed() ausführen?

          D.h. ich habe mehrere Threads in meiner Queue:
          1. Rufe nächsten Thread auf
          2. entferne es aus der Queue
          3. ändere Flag der Queue

          Danke schon mal im Voraus!

          Comment


          • #6
            Keine Ahnung, weil ich überhaupt nicht verstehe, was du machen willst.

            Punkt 3 deiner obigen Liste wird nicht mehr möglich sein, wenn der Thread mit Punkt 2 futsch ist.
            Mir ist auch wie gesagt nicht klar, was dieses Flag soll, an dem jeder Thread zu jeder Zeit eine Änderung vornehmen kann. Ich weiss auch nicht, was dagegen sprechen sollte aus dem Thread "procced" auszuführen.
            Christian

            Comment


            • #7
              Was ich habe ist wie man oben sehen kann eine Klasse Network , dass jede AnfrageThread in eine Queue steckt und ich möchte diese aus der Queue entnehmen und an die zur Verfügung stehenden SlaveServer schicken!

              Jeder AnfrageThread ist selber für das verschicken verantwortlich und soll eigentlich nur aktiviert werden sollte ein SlaveServer frei sein.

              Würde mich über jede Hilfe freuen!

              Comment


              • #8
                Dann muss es doch irgendwo eine Prüfung geben, die feststellt, ob ein Slave frei ist. Diese Prüfung sollte threadsicher sein und den nächsten/einen freien Slave zurückgeben.

                Wenn das im NetworkSlaveServerStatus passiert, reicht es doch dort die nächste Anfrage dem freien Slave - aus der Queue - zu übergeben.

                Es ist wohl definitiv der falsche Weg, in einer Klasse EINE Variable zu benutzen um x-Thread-zustände zu steuern.


                • Network: für die Verwaltung, Anfrage Threads werden in einer Queue gepackt
                • NetworkRequestThread: für jede Anfrage wird ein Thread gestartet
                • NetworkSlaveServerStatus: ein Thread der die Slave Server abhört
                • NetworkWorkerThread: der Anfrage-Threads aus der Queue holt und aufruft

                Wozu gibt es den letzten Thread?

                Die Klasse Network hat die Queue. Dann reicht es doch, wenn NetworkSlaveServerStatus einen freien Slave findet, die Queue ausliest, und an den Slave reicht. Neue Anfragen werden durch NetworkRequestThread in die Queue geschrieben.
                Zuletzt editiert von Christian Marquardt; 07.09.2011, 15:33.
                Christian

                Comment


                • #9
                  Könnte es so klappen?

                  Code:
                  public class NetworkWorkerThread implements Runnable{
                      
                      private Network net;
                      private NetworkRequestThread netThread;
                      
                      public NetworkWorkerThread(NetworkRequestThread netThread, Network net) {
                          this.netThread = netThread;
                          this.net = net;
                      }
                  
                      
                      
                      public void startThread() {
                          new Thread(this).start();
                      }
                      
                      public void run() {
                          synchronized(this){
                              while(net.getSlave1Status()|net.getSlave2Status() == true){
                                  NetworkRequestThread netThreadtemp; 
                                  netThreadtemp = (NetworkRequestThread) net.queueRemoveNext();
                                  netThreadtemp.proceed();                
                              }
                          }
                      }
                  }
                  Code:
                  public class Network {
                  
                      private ServerSocket serverSkt;
                      private int port = 4444;
                      private boolean alive = false;
                      private Window win;
                   
                      public static Queue q = new LinkedList();
                      public static boolean slaveServer1Status = false;
                      public static boolean slaveServer2Status = false;
                      
                      
                  
                      public Network(Window view) {
                          this.win = view;
                  
                      }
                  
                      public void listen() {
                          try {
                              serverSkt = new ServerSocket(port);
                              alive=true;
                              NetworkRequestThread netThread = null;
                              new NetworkSlaveServerStatus(this).startThread();
                              new NetworkWorkerThread(netThread,this).startThread();
                              
                              while(alive){
                                  Socket skt = serverSkt.accept();
                                  netThread = new NetworkRequestThread(skt,this);
                                  q.add(netThread); 
                              }           
                          }
                  
                          catch (IOException ex) {
                           }
                      }
                      
                              
                      public Window getWin() {
                          return win;
                      }
                  
                      public void setWin(Window win) {
                          this.win = win;
                      }
                      
                      
                  
                      public Object queueRemoveNext() {
                         return q.remove();  
                      }
                      
                      
                      
                      
                      
                      public boolean getSlave1Status() {
                          return slaveServer1Status;
                      }
                  
                      public void setSlave1Status(boolean slaveServer1Status) {
                          Network.slaveServer1Status = slaveServer1Status;
                      }
                      
                      public boolean getSlave2Status() {
                          return slaveServer2Status;
                      }
                  
                      public void setSlave2Status(boolean slaveServer2Status) {
                          Network.slaveServer2Status = slaveServer2Status;
                      }
                  
                  }

                  Comment

                  Working...
                  X