Hi,

On Wed, 21 Mar 2001, Alexander Kogan wrote:

> marc fleury wrote:
> > 
> > Just out of curiousity Simone...
> > 
> > when we benched at SUN one of the big difference under load was the thread
> > management.
> > 
> > The best in terms of resource usage was put the thread to sleep (with a 5
> > sec timeout) and notify (1) and that REALLY flew and scaled REALLY well
> > because the usage of CPU and sync was really low.
> 
> This would be very good idea. For now, especially on Tru64 with JDK 1.3-1
> LOKING-WAITING stuff eats a lot CPU and much more slow than on Sun.
> 
> And why do we need timeout there? Is it possible to implement a sort
> of queue for that? Than you can put a new thread to the waiting list and
> when the current thread is done with the transaction it can call
> notify to release the tread from the waiting list.
> Am I talking junk?

i've developed fair queue (it maintains the order of requests) for
obtaining exclusive lock (token). Maybe it could help ...


Dragan

// Distributable under GPL License
// Author Dragan Milic ([EMAIL PROTECTED])

import java.lang.*;
import java.util.*;

public class FairThreadQueue {
    LinkedList threadQueue=new LinkedList();
    HashSet threadSet=new HashSet();

    public FairThreadQueue() {
    }

    public void getToken() {
        Lock lock=null;
        Thread currentThread=Thread.currentThread();
        synchronized (this) {
            
            // sanity check, for reenterant beans
            if (threadSet.contains(currentThread)) 
                return;
                    
            threadSet.add(currentThread);
            lock=new Lock();
            threadQueue.add(lock);          
            
            // if there are no other threads in queue this one can have a token
            if (threadQueue.size() == 1) 
                return;                     
        }
        // ok, there is some thread running ... just wait in queue    
        lock.waitForUnlock();
    }
    
    public synchronized void returnToken() {
        Thread currentThread=Thread.currentThread();

        // another sanity check 
        if (!threadSet.contains(currentThread))
            return;

        // if current thread is active it must be first in queue
        threadQueue.removeFirst();
        threadSet.remove(currentThread);
        
        if (threadQueue.size() >0) {
            Lock first=(Lock)threadQueue.getFirst();
            first.unlock();
        }
        
    }


    // because of possible lost wait there is necesarry to check
    // if lock has been unlocked
    public static class Lock {

        boolean unlocked=false;
        
        public void Lock() {
        }
                
        public synchronized void waitForUnlock() {
            if (unlocked)
                return;
            else {
                try {
                    wait();
                } catch (InterruptedException ie) {
                }
            }
        }
        
        public synchronized void unlock() {
            unlocked=true;
            notify();
        }
    }


    // below is only a test for functionality and fairness
    
    public static void main(String argv[]) {
        FairThreadQueue queue=new FairThreadQueue();
        for (int i=0; i<200; i++) {
            QueueTest qt=new QueueTest(queue, i);
            qt.start();
        }
    }
    
    public static class QueueTest extends Thread {
        static int count=0;
        FairThreadQueue ftq;
        int threadNr;

        QueueTest(FairThreadQueue ftq, int threadNr) {
            this.ftq=ftq;
            this.threadNr=threadNr;
        }

        public void run() {
            ftq.getToken();
            // test for reenterant test :)
            ftq.getToken();
            System.out.println("current counter "+count+" thread "+threadNr);
            count++;
            ftq.returnToken();
        }
    }
}

Reply via email to