?
Solved

Synchronizing threads

Posted on 2003-03-16
13
Medium Priority
?
250 Views
Last Modified: 2010-03-31
Hi ppl, need help on this. This load balancing program works well initially until i add in the timer and timertask. The send method found in the NetworkProvider class starts to throw a NegativeArraySizeException as the value of length is -1. I deliberatly comment out the part where the server replies and close the socket but it seems that the client still get a End Of stream. So i change it such that if -1 is detected for length it will throw an Exception and repeat the request. But other exceptions start to be thrown all over the place. Can anyone help me on this, is the synchronized keywork used correctly ?

import CKSException;
import Parser;
import NetworkProvider;
import java.net.*;
import java.io.*;
import java.util.*;

public class LoadBalancer{
  private Parser parser;
  private NetworkProvider networkProvider;
  private int current;
  private int next;

  private Timer timer;

  public LoadBalancer(String filename) {
    parser= new Parser(filename);
    next=0;
    timer = new Timer(true);
    timer.schedule(new Task(),2000,2000);
  }

  public LoadBalancer() {
    parser= new Parser("comms.cfg");
    next=0;
    timer = new Timer(true);
    timer.schedule(new Task(),2000,2000);
  }

  class Task extends TimerTask {
    public synchronized void run() {
      System.out.println("Updating") ;
      parser.tokenize(parser.read()) ;
      next=0;
    }
  }

  public synchronized byte[] send(byte[] data) throws CKSException{
    //Decide the load-balancing algorithm to use
    byte[] receiveData=null;
    boolean loop=false;
    System.out.println("Start of method") ;
    do{
      //Abort sending of commands
      if (parser.getAddressTable().length ==0 ){
        throw new CKSException();
      }

      try{
        if (parser.getLoadBalanceAlgo()==Parser.ROUNDROBIN ) {
          //Decide server to be used
          //If method is to be used then let the method instantiate the NetworkProvider

          current=next;
          setNext();
*************************************************************************

Receive NullPointerException for the statement below
*************************************************************************

          networkProvider = new NetworkProvider(parser.getAddressTable(current),parser.getPortTable(current),parser.getTimeOut());
        }

        else if (parser.getLoadBalanceAlgo() ==Parser.RANDOM ) {
          //Decide server to be used
          //If method is to be used then let the method instantiate the NetworkProvider
          do {
            current=(int)(Math.random()*parser.getAddressTable().length) ;
          }while(current==parser.getAddressTable().length);
          networkProvider = new NetworkProvider(parser.getAddressTable(current),parser.getPortTable(current),parser.getTimeOut());
        }

        //Sends the data using the NetworkProvider
        receiveData = networkProvider.send(data);
        loop=false;

      }catch(ConnectException e) {
        //Since connection is never established socket need not be close
        System.out.println("Connection refused ... Check if server is operational");
        //break; //either break or return so that e seq is skipped

        change();
        setFailoverNext ();
        loop=true;
      }catch(SocketException e){
        try {
          networkProvider.getSocket().close() ;
        }catch(IOException ee) {
          System.out.println(e) ;
        }

        System.out.println("Server error ...  Check the socket of the server" );
        change();
        setFailoverNext ();
        loop=true;
      }catch(InterruptedIOException e) {
        try {
          networkProvider.getSocket().close() ;
        }catch(IOException ee) {
          System.out.println(e) ;
        }

        System.out.println("Timeout ... Response not received" );
        change();
        setFailoverNext ();
        loop=true;
      }catch(CKSNegativeIndexException e) {
        try {
          networkProvider.getSocket().close() ;
        }catch(IOException ee) {
          System.out.println(e) ;
        }
        System.out.println("Error ... Message resent") ;

        loop=true;
      }catch(IOException e) {
        ;
      }
    }while(loop);
    System.out.println("End of method") ;
    return receiveData;
  }

  private void change() {
    //Used to remove the current server from the list of servers
    String[] tempAddress=new String[parser.getAddressTable().length -1];
    int[] tempPort=new int[parser.getPortTable().length -1];
    //For copying whatever is before the invalid server
    if (current!=0) {
      System.arraycopy(parser.getAddressTable() ,0,tempAddress,0,current) ;
      System.arraycopy(parser.getPortTable() ,0,tempPort,0,current) ;
    }
    //For copying whatever is after the invalid server
    if(current!=parser.getAddressTable().length -1){
      System.arraycopy(parser.getAddressTable(),current+1,tempAddress,current,tempAddress.length -current) ;
      System.arraycopy(parser.getPortTable(),current+1,tempPort,current,tempPort.length -current) ;
    }
    parser.setAddressTable(tempAddress) ;
    parser.setPortTable(tempPort) ;
  }

  private void setNext(){
    //Next represents which set it is pointed to
    //For example a server list of 3 sets next can have numbers ranging form 0-2

    //if next is pointing to the last set of address
    if (next==parser.getAddressTable().length -1)
      next=0;
    else
      next++;
  }

  private void setFailoverNext () {
    //If next is not pointing to the first set back 1 step
    //Because the array size has shrink due to the removal of a server
    //However if next is pointing to the first set there will be
    //no need to shift as the change in array size does not affect it
    if (next!=0)
      next--;
  }

  public NetworkProvider getNetworkProvider () {
    return networkProvider;
  }
}

import java.io.*;
import java.net.*;
import CKSNegativeIndexException;

import Utility;

public class NetworkProvider {
  private Socket socket;
  private DataOutputStream dout;
  private DataInputStream din;

  public NetworkProvider(String host, int port, int timeOut) throws IOException{
      socket = new Socket(host,port);
      socket.setSoTimeout(timeOut * 100) ;

      dout= new DataOutputStream(socket.getOutputStream() );
      din = new DataInputStream(socket.getInputStream() );
  }

  public byte[] send(byte[] data) throws IOException, CKSNegativeIndexException {
    dout.write(data) ;

    byte[] buffer= new byte[100];  //A Big Buffer space
********************************************************

NegativeArraySizeException is being thrown here
**********************************************************
    int length=din.read(buffer) ;
    if (length ==-1) {
      System.out.println("-1 detected") ;
      throw new CKSNegativeIndexException();
    }
    System.out.println(length) ;
    byte[] returnData= new byte[length];
    System.arraycopy(buffer, 0, returnData,0,length);

    return returnData;
  }

  public Socket getSocket() {
    return socket;
  }
}
0
Comment
Question by:Leoleo
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
  • 2
13 Comments
 
LVL 2

Expert Comment

by:functionpointer
ID: 8157235

 class Task extends TimerTask {
>>>>public synchronized void run() {
     System.out.println("Updating") ;
     parser.tokenize(parser.read()) ;
     next=0;
   }
 }

this is unnecessary, since java.util.Timer is single threaded anyway. Which may well be the problem. java.util.Timer is a pretty bad implementation.

maybe i missed something, but I dont see where this program is multi threaded.
0
 

Author Comment

by:Leoleo
ID: 8163501
i'm really new with java actually so perhaps u can give me some suggestions on how to implement this task. My task requires me to send message to server (switchig between 3 servers) and if a server fail the address of the server will be remove from the list of addresses. After a specific time interval the client will update the list of address from a file. So in my case the timer will be a thread and the sending will be another thread.

>>>java.util.Timer is a pretty bad implementation.
As in the class itself is implemented badly or i shouldn't use the class in the first place?
0
 

Author Comment

by:Leoleo
ID: 8163539
i'm really new with java actually so perhaps u can give me some suggestions on how to implement this task. My task requires me to send message to server (switchig between 3 servers) and if a server fail the address of the server will be remove from the list of addresses. After a specific time interval the client will update the list of address from a file. So in my case the timer will be a thread and the sending will be another thread.

>>>java.util.Timer is a pretty bad implementation.
As in the class itself is implemented badly or i shouldn't use the class in the first place?
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Expert Comment

by:SpideyMod
ID: 8173832
A request for a refund has been made.  Experts you have 72 hours to object.

SpideyMod
Community Support Moderator @Experts Exchange
0
 
LVL 2

Expert Comment

by:functionpointer
ID: 8175958
>>is the synchronized keywork used correctly ?
the answer was no.

as long as you dont create multiple instances of your LoadBalancer, since your send method is synchronized, this should be fine. What you need to synchronize depends on how you use this.


>>As in the class itself is implemented badly or i shouldn't use the class in the first place?
using Timer is up to you. for what you are having it do, it depends on the length(time) of your parser.tokenize( parser.read() ) method and how often you plan to run it. It will not behave as you might think. Give Timer.java and TimerTask.java a look over. In TimerThread's mainLoop, you will see what i mean. If this single thread operation without respect to scheduled times is acceptable operation for you, great. Use it.  Just know and respect how it functions.

when your Task alters the list, you'll need an object lock on your parser while it is loading so no other Thread can read a half created list.
0
 

Author Comment

by:Leoleo
ID: 8178353
>>as long as you dont create multiple instances of your >>LoadBalancer, since your send method is synchronized, >>this should be fine. What you need to synchronize >>depends on how you use this.

nope there is only 1 instance of loadbalancer

>>for what you are having it
>>do, it depends on the length(time) of your >>parser.tokenize( parser.read() ) method and how often >>you plan to run it.
the frequency of the when the parser.tokenize(parser.read()) is already specify in the Timer.schedule method.

>>It will not behave as you might think.
I look at the Timer n TimerTask specs before n i find it acceptable for use in my case. So am i correct to say tat the timer class will execute the TimerTask at a fix interval.

>>If this single thread operation without respect to >>scheduled times is acceptable operation for you, great.
u mean the timer class do not abide to the scheduled time?

>>when your Task alters the list, you'll need an object >>lock on your parser while it is loading so no other >>Thread can read a half created list.
i only way i noe of to lock an object is to use the synchronize keyword is there anyother way for me 2 do it?

Tks....Hope to get a reply from u soon
0
 
LVL 2

Accepted Solution

by:
functionpointer earned 400 total points
ID: 8179219
>>I look at the Timer n TimerTask specs

No... The specs are just javadocs about how the programmer 'wanted' the code to work. I mean read the Java code for Timer and TimerTask. It may be a pain in the butt to understand what's happening in there, but once you do, you'll see what i mean and it will answer alot of your questions.

>>u mean the timer class do not abide to the scheduled time?
Timer doesnt care about the actual 'time' you want the task to run. It just adds the interval to the current time and reschedules it. If your task took longer that the interval and your task comes up in the queue and is late, it will run immediately ( not necessarily at the proper time, ie- top of the hour ).



Yes, synchronized keyword is the way to lock the object. I just meant to lock the 'object' while it was loading as opposed to locking a 'method'. like:
synchonized( parser )
{
  parser.someMethod();
  parser.someOtherMethod();
}

that way, you own the parser object while its loading. noone else can access this parser instance.

0
 

Expert Comment

by:SpideyMod
ID: 8191001
This question still appears active.  I will defer until another request for a refund has been made.

SpideyMod
Community Support Moderator @Experts Exchange
0
 

Author Comment

by:Leoleo
ID: 8200870
>>Timer doesnt care about the actual 'time' you want the >>task to run. It just adds the interval to the current >>time and reschedules it. If your task took longer that >>the interval and your task comes up in the queue and is >>late, it will run immediately ( not necessarily at the >>proper time, ie- top of the hour ).
I see, that is alrite for my program as i do not require it timertask to execute at the exact moment when the time elapsed besides i expected it to be so.

>>Yes, synchronized keyword is the way to lock the >>object. I just meant to lock the 'object' while it was >>loading as opposed to locking a 'method'. like:
>>synchonized( parser )
>>{
>> parser.someMethod();
>> parser.someOtherMethod();
>>}
>>that way, you own the parser object while its loading. >>noone else can access this parser instance.

ok, but what is the difference between locking an object using the synchronized keyword and locking the method like what i have done? why doesn't it work when i use the synchronized keyword on the method?
0
 

Author Comment

by:Leoleo
ID: 8208473
So where can i find the java code for timer and timertask? Do I have to download it ? So that i could better understand what is happening underneath
0
 
LVL 2

Expert Comment

by:functionpointer
ID: 8215595
the source (.java files) are in the src.zip, which is part of the j2sdk.
0
 

Author Comment

by:Leoleo
ID: 8221865
yup i found the source files, tks. the questions i posted before that???
0
 

Author Comment

by:Leoleo
ID: 8221902
tks i found the source file. but what about the question i posted before that?
0

Featured Post

Want to be a Web Developer? Get Certified Today!

Enroll in the Certified Web Development Professional course package to learn HTML, Javascript, and PHP. Build a solid foundation to work toward your dream job!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
Suggested Courses
Course of the Month11 days, 22 hours left to enroll

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question