#1
  1. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Oct 2001
    Location
    New Zealand
    Posts
    1,774
    Rep Power
    24

    Unhappy Multithreading and passing values


    I am trying to get my head around multithreading, unfortunately I am coming up against a few problems. In my script I have the following:

    class produceInt extends Thread {
    private holdInteger holdInt;
    private int ranValue;
    public produceInt(holdInteger h) {
    super("produceInt");
    holdInt = h;
    }
    public void run() {
    holdInt.setSharedInteger();
    }
    }
    class consumeInt extends Thread {
    private holdInteger holdInt;
    public consumeInt(holdInteger h) {
    super("consumeInt");
    holdInt = h;
    }
    public void run() {
    int val = holdInt.getSharedInteger();
    }
    }

    class holdInteger {
    private int sharedInt;
    public void setSharedInteger() {
    sharedInt = 1 + (int) (Math.random() * 1000);
    }
    public int getSharedInteger() {
    return sharedInt;
    }
    }

    .. that creates a random integer and stores it in the sharedInt variable within the holdInteger class. This works well enough, but when retrieving the integer again I just get a value of 0 in consumeInt class. So what am I doing wrong?

    Also, how can I pass the random integer generated back to my main class, main function? Or can I not? What I want to do is create an array of x amount of random integers, to be used by the main class, but how I do this is beyond me?

    So far, in the main class I have:

    for (int i = 0; i < numInts; i++) {
    holdInteger h = new holdInteger();
    produceInt p = new produceInt(h);

    consumeInt c = new consumeInt(h);

    p.start();

    c.start();
    }

    that makes the call to create these integers, so is that the best way of doing it?

    Help would be so much appreciated.
  2. #2
  3. No Profile Picture
    Moderator =(8^(|)
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2002
    Location
    Sacramento, CA
    Posts
    1,710
    Rep Power
    14
    Does this have to use threads? Unless you need (or really want) to use multithreading for some reason, there are easier ways to do this.
    -james
  4. #3
  5. No Profile Picture
    Moderator =(8^(|)
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2002
    Location
    Sacramento, CA
    Posts
    1,710
    Rep Power
    14
    You might try doing

    Code:
     
    p.start();
    c.start();
    c.sleep( 1000 );
    It looks like the consumer is trying to read the value before the producer sets it.

    Let me reiterate, though, that this *really* isn't a situation to use threads for.
    -james
  6. #4
  7. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Oct 2001
    Location
    New Zealand
    Posts
    1,774
    Rep Power
    24
    Yeah, I finally figured the sleep bit out yesterday. Cheers for the reply.

    I know, threads aren't a sensible thing to use in this situation, I wouldn't use threads, but hey, it's not my choice... if I'm going to get accredited for this Java module I'm doing then I have to do the thing using threads.

    I also have to limit the number of processors used for the sequence. Does this mean limit the number of threads or is there some big Java function that says only use x amount of processors, I don't know. It's beyond me really. Can't find any examples on the WWW and the tutor isn't emailing back. Any ideas? Here's my new code:

    Code:
    // import packages
    import java.io.*;
    import javax.swing.*;
    import java.util.*;
    import java.text.*;
    
    public class multithread {
       public static void main( String args[] )
       {
          HoldIntegerSynchronized h = new HoldIntegerSynchronized();
    	  // get values
          String intString = JOptionPane.showInputDialog("Enter number of integers to be used in calculation:");
          h.setIntegers(Integer.parseInt(intString));
          String procString = JOptionPane.showInputDialog("Enter number of processors to be used in calculation:");
          h.setProcessors(Integer.parseInt(procString));
          ProduceInteger p = new ProduceInteger( h );
          ConsumeInteger c = new ConsumeInteger( h );
    
          p.start();
          c.start();
       }
    }
    class ProduceInteger extends Thread {
       private HoldIntegerSynchronized pHold;
    
       public ProduceInteger( HoldIntegerSynchronized h )
       {
          super( "ProduceInteger" );
          pHold = h;
       }
    
       public void run()
       {
        // get start time
          Date start = new Date();
          int processors = pHold.getProccesors(); // number of processors to be used
    
          pHold.setStart();
          do {
             // sleep thread
             try {
                Thread.sleep( (int) ( Math.random() * 3000 ) );
             }
             catch( InterruptedException e ) {
                System.err.println( e.toString() );
             }
    
             pHold.setSharedInt(1 + (int) (Math.random() * 1000));
          } while (pHold.getStatus() == 1); // when the set number of integers are reached this returns 1
       }
    }
    class ConsumeInteger extends Thread {
       private HoldIntegerSynchronized cHold;
    
       public ConsumeInteger( HoldIntegerSynchronized h )
       {
          super( "ConsumeInteger" );
          cHold = h;
       }
    
       public void run()
       {
          int val, sum = 0, currentInt = 1, x[];
          int numInts = cHold.getIntegers(); // number of integers to be used
          x = new int[numInts];
          do {
             // sleep thread
             try {
                Thread.sleep( (int) ( Math.random() * 3000 ) );
             }
             catch( InterruptedException e ) {
                System.err.println( e.toString() );
             }
    
             val = cHold.getSharedInt();
    		 // calculate using returned integer
            sum += val;
            x[currentInt - 1] = sum;
             currentInt ++;
          } while ( currentInt != numInts + 1);// return set number of integers then stop
          cHold.setEnd();
          cHold.setStatus();
          Arrays.sort(x);
    
          // create a save dialog box
          JFileChooser fileChooser = new JFileChooser();
          fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
          int result = fileChooser.showSaveDialog(null);
          if (result == JFileChooser.CANCEL_OPTION) {
            System.exit(0);
          } else {
            File filename = fileChooser.getSelectedFile();
            if (filename == null || filename.getName().equals("")) {
              JOptionPane.showMessageDialog(null, "Ivalid File Name","Invalid File Name", JOptionPane.ERROR_MESSAGE);
            } else {
              try {
                // output the data
                DataOutputStream output;
                output = new DataOutputStream( new FileOutputStream(filename));
                for (int i = 0; i < x.length; i++) {
                    output.writeBytes(String.valueOf(x[i]) + "\n");
                }
                output.writeBytes("\nTime taken: " + String.valueOf(cHold.getTaken()) + " milliseconds");
                output.flush();
                output.close();
                JOptionPane.showMessageDialog(null, "File written.");
              } catch (IOException e) {
                JOptionPane.showMessageDialog(null, e);
              }
            }
          }
          System.exit(0);
       }
    }
    class HoldIntegerSynchronized {
       private int sharedInt = -1, mayContinue = 1, processors = 1, integers = 0;
       private boolean writeable = true;  // condition variable
       private Date end, start;
       private long timeTaken;
    
       public synchronized void setSharedInt(int val)
       {
          while ( !writeable ) {  // not the producer's turn
             try {
                wait();  
             }
             catch ( InterruptedException e ) {
                e.printStackTrace();
             }
          }
          sharedInt = val;
    
          writeable = false;
          notify();  // tell a waiting thread to become ready
       }
    
       public synchronized int getSharedInt()
       {
          while ( writeable ) {   // not the consumer's turn
             try {
                wait();
             }
             catch ( InterruptedException e ) {
                e.printStackTrace();
             }
          }
    
          writeable = true;
          notify();  // tell a waiting thread to become ready
          return sharedInt;
       }
       public int getStatus() {
       // return whether current position in integerCount is valid
         return mayContinue;
       }
       public void setStatus() {
       // set end of integers required has been reached
         mayContinue = 0;
       }
       public void setStart() {
        start = new Date();
       }
      public void setEnd() {
        end = new Date();
      }
      public long getTaken() {
        timeTaken = end.getTime() - start.getTime();
        return timeTaken;
       }
      public void setProcessors(int i) {
        processors = i;
      }
      public int getProccesors() {
       return processors;
      }
      public void setIntegers(int i) {
        integers = i;
      }
      public int getIntegers() {
       return integers;
      }
    }
  8. #5
  9. No Profile Picture
    Moderator =(8^(|)
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2002
    Location
    Sacramento, CA
    Posts
    1,710
    Rep Power
    14
    I wonder if by number of processors they mean number of threads? You'd have rework your code a little to launch multiple threads (and for what you're doing, more than one thread isn't going to help ), but you could do it.

    What you have looks really good, though.
    -james
  10. #6
  11. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Oct 2001
    Location
    New Zealand
    Posts
    1,774
    Rep Power
    24
    Probably does mean number of threads. So how could this be done?

    A for loop and a stack counter or something? If so, where in the code?

IMN logo majestic logo threadwatch logo seochat tools logo