Note that there are some explanatory texts on larger screens.

plurals
  1. POJava Threads reading and writing from a shared stack array
    text
    copied!<p>The result of this program should be the same with 1 or 2 or 3 threads. However, the result with thread 1 is the real one. I think I am meshing up with shared and private variables, what am I doing wrong? Threads have to read from the stack an interval and then calculate the quadrature model.If the error is small enough (i.e. within the specified accuracy) then we have the solution. If the error is still too large, the interval is divided into two with half the required error given to each half of the interval. The quadrature is applied again and so on until the error is small enough. The main problem arises through premature termination of the threads. The stack may be empty, but another thread might be about to place new tasks on it. The solution to this is to keep a count of the "active" threads, that is, the ones which are currently processing an interval. Then the code should terminate only when the stack is empty and there are no active threads...</p> <p>Please, any help would be very appreciate it?</p> <p>Cheers</p> <pre><code> import java.lang.Integer; class quadtest { /* Adaptive Quadrature Code. Finds the value of an integral of a function on a closed interval to a specified accuracy. */ public static void main (String args[]) { int nthreads = Integer.parseInt(args[0]); double left, right, eps; double start_time, time; Quad quad =null; //Counter counter = new Counter(); left = 0.0; right = 1.0; eps = 1.0E-11; System.out.println("Adaptive Quadrature Program \n"); System.out.println("eps="+eps+" n=10000"); start_time = System.currentTimeMillis(); //Start threads Thread thread_object [] = new Thread[nthreads]; for(int i=0;i&lt;nthreads;i++){ quad = new Quad(left,right,eps,i,nthreads); thread_object[i]=new Thread(quad); } for(int i=0;i&lt;nthreads;i++){ thread_object[i].start(); } //Join the threads for(int i=0;i&lt;nthreads;i++){ try{ thread_object[i].join(); }catch(InterruptedException x){} } time = (double) (System.currentTimeMillis()-start_time) / 1000.; System.out.println("Result = " + quad.getResult() ); System.out.println("Execution time = " + time + " seconds "); } } import java.lang.Runnable; import java.util.concurrent.atomic.AtomicInteger; class Quad implements Runnable{ //Shared Variables static volatile double [][] stack; static volatile boolean first=false; static volatile double FinalResult; static AtomicInteger threadCounter; static AtomicInteger writing; static AtomicInteger stackpointer; static int nthreads; //Constants static final int stacksize = 1000; static final int il = 0; static final int ir = 1; static final int ie = 2; static final int dims = 3; //Private Variables private int tid; double left,right,eps; private double result; private double l,r,ep; public Quad(double left, double right, double eps,int tid,int nthreads) { this.left = left; this.right = right; this.eps = eps; this.tid=tid; Quad.nthreads = nthreads; result = 0.0; //Only one thread will do it if(first==false){ first=true; stack = new double [dims][stacksize]; threadCounter= new AtomicInteger(0); writing = new AtomicInteger(0); stackpointer = new AtomicInteger(1); stack[il][stackpointer.get()] = left; stack[ir][stackpointer.get()] = right; stack[ie][stackpointer.get()] = eps; FinalResult=0.0; } } public void run(){ stackops(); add(); } public void stackops() { double abserror,m, est1, est2; while ((stackpointer.get() &gt;= 1)|| threadCounter.get()&gt;0) { // Pop next interval off stack. synchronized (this){ threadCounter.incrementAndGet(); while (writing.get()==1){} pop(); } // Compute estimates. m = 0.5 * (l + r); est1 = 0.5 * (r - l) * (func(l) + func(r)) ; est2 = 0.5 * ((m - l) * (func(l) + func(m)) + (r - m) * (func(m) + func(r))); abserror = Math.abs(est2-est1) / 3.0; // Check for desired accuracy: push both halves onto the // stack if not accurate enough. if (abserror &lt;= ep) { result += est2; //System.out.println("ERROR-&gt;ID "+tid+"-abserror="+abserror+"-ep="+ep ); //System.out.flush(); } else { if (stackpointer.get()+ 2 &gt; stacksize) { System.out.println("Stack too small, try stacksize = " + 2*stacksize); } //Push into the stack synchronized (this){ push(m); } }//end else threadCounter.decrementAndGet(); }//end while }//end method private synchronized void add(){ FinalResult +=result; } private void pop(){ if(stackpointer.get()&gt;0){ l = stack[il][stackpointer.get()]; r = stack[ir][stackpointer.get()]; ep = stack[ie][stackpointer.get()]; stackpointer.decrementAndGet(); } } private void push (double m){ writing.set(1); if(stackpointer.get()&gt;=-1){ stackpointer.incrementAndGet(); stack[il][stackpointer.get()] = l; stack[ir][stackpointer.get()] = m; stack[ie][stackpointer.get()] = ep * 0.5; stackpointer.incrementAndGet(); stack[il][stackpointer.get()] = m; stack[ir][stackpointer.get()] = r; stack[ie][stackpointer.get()] = ep * 0.5; } writing.set(0); } public double getResult(){ return FinalResult; } private double func(double x) { double q; int n; n = 10000; q = 1000.0; for(int i=0;i&lt;n;i++) { q -= x; } if (q == 1.0e10) System.out.println("q = " + q); return x * x; } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload