Some help in Java

  • Thread starter Thread starter Eric.
  • 8 comments
  • 847 views

Eric.

Premium
Messages
8,515
Messages
GTP_Eric
Messages
Ebiggs
I'm working on a project due next week that is for interprocess communication. Its the producer/consumer problem. Though none of that is really too important to my issue.


I'm doing this in Java because I don't know C, so instead I'm creating two threads and performing operations on an integer array instead of a file or on shared memory like the lab suggests. So in my Main class I have a 10-item integer array named "buffer" created. There is also an integer named "r" that I'm using Random() with to create the numbers that will go into the array (not much point in that to be honest, just doing it).

The threads' execution code is in their class file "ChildThread", and at the moment it looks like this:

Code:
public class ChildThread extends Thread {

    //variables
    private String name;


    //constructor
    public ChildThread(String aName){

        name = aName;
    }

    public void run(){
        
       
       if (name.equals("Producer")){
           int i = 0; //index value for buffer array
           int data = r;
           while (i < 10){
               buffer[i] = r+1;   ***THIS LINE IS WHERE THE PROBLEM IS***
           }
        }
       if(name.equals("Consumer")){
           int i = 0; //index value for buffer array
       }
    }
}

The problem is that the variable "r" and the int array "buffer" are not visible inside this class where the actual operations are going to be done. What can I do to make that work?
 
I assume the buffer array and the r variable are initialized in the Thread superclass? Were those initialized as global variables in the Thread superclass, or were they initialized in a method within Thread?

Also, I was never really good at Java programming, but don't you have to pass the the array and the variable into the subclass by calling the superclass?
 
I think I got it.

[url="http://www.suite101.com/content/java-variables-and-operators-a80649"
Link[/url]]Globals in Java

Global variables are those that can be used throughout a program or programs. If the float variable curTotal is a global, it can be called from anywhere. In order to use globals, they must be declared in a special static class:

public class Global{

public static float curTotal=0;

}

This class is named Global, but any legal name can be used. Now the curTotal can be called in any class in the same program:

public class Global{

public static float curTotal=0;

}

public class total {

public static void main(String args[]) {

Global.curTotal = Global.curTotal + 100;

System.out.println(Global.curTotal);

}

Read more at Suite101: Java Variables: Declaring, Initializing, and the Simple Global http://www.suite101.com/content/java-variables-and-operators-a80649#ixzz1DCYootx8
 
I see you got it working but I'll show you how I'd do it since I saw some odd things in the code you've shown:

Code:
public class ChildThread extends Thread {

    //variables
    private String name;
    private Random random; //let the producer actually produce the value
    private int buffer[]; /* no need to make the buffer a "global" array, you can just store a reference
                            for it here */

    //constructor
    public ChildThread(String aName, int buffer[]){
        name = aName;
        this.buffer = buffer; //save the reference to the buffer just like you did with the string.
    }

    public void run(){
       if (name.equals("Producer")){
           int i = 0; //index value for buffer array

           while (i < 10){
               buffer[i++] = random.nextInt()+1; /* producer will be actually producing the values here.
                                                Also, don't forget to increment the i value or you will 
                                                overwrite the first position of the buffer only.*/
           }
        }
       else if(name.equals("Consumer")){ //Should use else if instead of just if since it can only be one or the other.
           int i = 0;

           //isn't the consumer supposed to do something here?
       }
    }
}

I'm a bit rusty so it's possible I'm making a mistake somewhere, but it should be working fine.

I believe you're aware you still have the producer/consumer problem here since you have 2+ threads messing around with the same buffer. You need a bunch of locks carefully placed to achieve mutual exclusion. Also, your consumer is not really doing anything.
 
Last edited:
The code was far from complete. I had just come to the point where I didn't have access to my variable and array and stopped until I found that solution.

The Producer/Consumer process is all there now and the code is complete.

Here's my complete source code:

Main:
Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package producerconsumer;
import java.util.*;
/**
 *
 * @author Ebiggs
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here

        //variables
        //int[] buffer = new int[10]; //the shared resource of the threads
        // int r; // will be the first item, generated randomly from 1 to 99

        //creating a number to base items off of
        Random generator = new Random();
        Data.r = generator.nextInt(90)+1;
        
        
        //Threads declared
        ChildThread p = new ChildThread("Producer");
        ChildThread c = new ChildThread("Consumer");

       /* Thread t1 = new Thread(p);
        Thread t2 = new Thread(c);
        t1.start();
        t2.start(); */

        p.start();
        c.start();
    }

}

ChildThread:
Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package producerconsumer;
import java.util.*;
/**
 *
 * @author Ebiggs
 */
public class ChildThread extends Thread {

    //variables
    private String name;


    //constructor
    public ChildThread(String aName){

        name = aName;
    }

    public void run(){



       if (name.equals("Producer")){
           Random sleepTime = new Random();
           int i = 0; //index value for buffer array
           int item = Data.r;
           int time;
           while (i < 10){
               while ((time = sleepTime.nextInt(4001)) < 1000){

               }

               Data.buffer[i] = item;
               System.out.printf("Thread P produced item " + Data.buffer[i] +
                       " at index " + i + " and is sleeping for " + time +"ms.\n");
               i++;
               item++;
               try{
               Thread.sleep(time);
               }
               catch( InterruptedException exception){
                   System.out.println("An Error occured in" + name);
               }
           }
           System.out.println("Thread P has finished.");
        }
       if(name.equals("Consumer")){
           Random sleepTime = new Random();
           int time;
           int oldItem;
           int i = 0; //index value for buffer array
           while (i < 10){
               while((time = sleepTime.nextInt(4001)) < 1000){

               }
               
               while (Data.buffer[i] == 0){
                   System.out.printf("Thread C found no item at index " + i +
                           " and is sleeping for " + time + "ms.\n");
                   try{
                   Thread.sleep(time);
                   }
                   catch( InterruptedException exception ){
                       System.out.println("An Error occurred in" + name);
                   }  
               } 
               oldItem = Data.buffer[i];
               Data.buffer[i] = -1;
               while ((time = sleepTime.nextInt(4001)) < 1000){

               }
               System.out.printf("Thread C consumed item " + oldItem +
                       " at index " + i + " and is sleeping for " + time + "ms.\n");
               i++;
               try{
                   Thread.sleep(time);
               }
               catch ( InterruptedException exception){
                   System.out.println("An Error occurred in" + name);
               }
           }
           System.out.println("Thread C has finished.\n");
       }
    }
}

Data:
Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package producerconsumer;

/**
 *
 * @author Ebiggs
 */
public class Data {
    public static int r;
    public static int[] buffer = new int[10]; //the shared resource of the threads

}

And a couple samples of the output:

Code:
Thread P produced item 88 at index 0 and is sleeping for 1833ms.
Thread C consumed item 88 at index 0 and is sleeping for 3205ms.
Thread P produced item 89 at index 1 and is sleeping for 2369ms.
Thread C consumed item 89 at index 1 and is sleeping for 2367ms.
Thread P produced item 90 at index 2 and is sleeping for 1857ms.
Thread C consumed item 90 at index 2 and is sleeping for 3736ms.
Thread P produced item 91 at index 3 and is sleeping for 1945ms.
Thread P produced item 92 at index 4 and is sleeping for 3174ms.
Thread C consumed item 91 at index 3 and is sleeping for 2617ms.
Thread P produced item 93 at index 5 and is sleeping for 3898ms.
Thread C consumed item 92 at index 4 and is sleeping for 2130ms.
Thread C consumed item 93 at index 5 and is sleeping for 3800ms.
Thread P produced item 94 at index 6 and is sleeping for 1660ms.
Thread P produced item 95 at index 7 and is sleeping for 2736ms.
Thread C consumed item 94 at index 6 and is sleeping for 1479ms.
Thread C consumed item 95 at index 7 and is sleeping for 2236ms.
Thread P produced item 96 at index 8 and is sleeping for 1682ms.
Thread P produced item 97 at index 9 and is sleeping for 3189ms.
Thread C consumed item 96 at index 8 and is sleeping for 1946ms.
Thread C consumed item 97 at index 9 and is sleeping for 1516ms.
Thread P has finished.
Thread C has finished.

Code:
Thread P produced item 33 at index 0 and is sleeping for 3011ms.
Thread C consumed item 33 at index 0 and is sleeping for 3426ms.
Thread P produced item 34 at index 1 and is sleeping for 3223ms.
Thread C consumed item 34 at index 1 and is sleeping for 3197ms.
Thread P produced item 35 at index 2 and is sleeping for 2329ms.
Thread C consumed item 35 at index 2 and is sleeping for 1931ms.
Thread C found no item at index 3 and is sleeping for 2763ms.
Thread P produced item 36 at index 3 and is sleeping for 3420ms.
Thread C consumed item 36 at index 3 and is sleeping for 1034ms.
Thread P produced item 37 at index 4 and is sleeping for 3465ms.
Thread C consumed item 37 at index 4 and is sleeping for 2224ms.
Thread C found no item at index 5 and is sleeping for 2252ms.
Thread P produced item 38 at index 5 and is sleeping for 1513ms.
Thread C consumed item 38 at index 5 and is sleeping for 1597ms.
Thread P produced item 39 at index 6 and is sleeping for 1096ms.
Thread P produced item 40 at index 7 and is sleeping for 1729ms.
Thread C consumed item 39 at index 6 and is sleeping for 1258ms.
Thread C consumed item 40 at index 7 and is sleeping for 3453ms.
Thread P produced item 41 at index 8 and is sleeping for 3473ms.
Thread C consumed item 41 at index 8 and is sleeping for 2274ms.
Thread P produced item 42 at index 9 and is sleeping for 3045ms.
Thread C consumed item 42 at index 9 and is sleeping for 1320ms.
Thread P has finished.
Thread C has finished.
 
Last edited:
OK that makes a lot more sense but you're still missing the most important aspect of the producer/consumer problem.

If you only have one of each, your code will work fine, but try running the same code with 2 consumers and 2 producers and problems will begin to appear. For example, 2 consumers consuming the same number, or a producer overwriting an item in the buffer which was not consumed yet. You need to synchronize the threads with locks to guarantee you won't have such problems.
 
Well that's odd. I remember learning about this problem specifically as an example on how important thread synchronization is when there are shared resources. But if it isn't the point in this case then yep, your code should be fine.
 
Back