对象池通知不起作用

Object Pool notify not working

我正在尝试创建一个对象池,程序和输出如下。

我在这里面临的问题是,在离开对象并调用 notify 或 notifyAll(程序中突出显示的第 1 行)之后,等待线程没有启动。

有人可以帮忙解决这个问题吗?

程序:-

import java.util.Hashtable;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

class ObjectPool implements Callable
{
    //Integer o;
    public ObjectPool()
    {
        //o = i;
    }

    public static ConcurrentLinkedQueue<Integer> locked = new ConcurrentLinkedQueue<Integer>();
    public static ConcurrentLinkedQueue<Integer> unlocked = new ConcurrentLinkedQueue<Integer>();
    static
    {
        int one = 1;
        int two = 2;
        int three = 3;
        int four = 4;
        unlocked.add(one);
        unlocked.add(two);
        unlocked.add(three);
        unlocked.add(four);
    }
    public Object get() throws InterruptedException
    {
        if(unlocked.size()>0)
        {
            Integer i = (Integer) unlocked.poll();
            //Integer o = new Integer((Integer) locked.size());
            locked.add(i);

            //System.out.println("New Object Created : "+o.toString()+" and acquired by Thread : "+Thread.currentThread().getName()+" for Object this : "+this.toString());
            return (i);
        }
        else
        {
            synchronized(this)
            {
                System.out.println("Thread entering into waiting state : "+Thread.currentThread().getName()+" for Object this : "+this.toString());
            wait();
            get();
            return null;
            }
        }
    }

    public void leave()
    {
        synchronized(this)
        {
        //  System.out.println(" Object left : "+o.toString()+" by Thread : "+Thread.currentThread().getName()+" for Object this : "+this.toString());
            Integer left = (Integer) locked.poll();
            unlocked.add(left);
            notify();                       **// Line 1**
        }
    }

    @Override
    public Object call() throws Exception 
    {
        Object o1 = get();
        System.out.println( "Thread going to sleep after getting lock : "+Thread.currentThread().getName()+".."+o1.toString());
        Thread.sleep(5000);
        System.out.println( "Thread Giving Notification : "+Thread.currentThread().getName()+".."+o1.toString());
        leave();
        return o1;
    }
}

public class Driver
{
    public static void main(String[] args) throws InterruptedException, ExecutionException
    {
        System.out.println(" Main method");


        ObjectPool[] op = {new ObjectPool(),new ObjectPool(),new ObjectPool(),new ObjectPool(),new ObjectPool(),new ObjectPool(),new ObjectPool(),new ObjectPool()};

        ExecutorService es = Executors.newFixedThreadPool(8);

        for(ObjectPool o :op)
        {
            es.submit(o);
        }

        //System.out.println(" p1 to p4 will leave the lock now");


    }
}

输出:-

Main method
Thread going to sleep after getting lock : pool-1-thread-1..1
Thread going to sleep after getting lock : pool-1-thread-3..2
Thread going to sleep after getting lock : pool-1-thread-2..3
Thread going to sleep after getting lock : pool-1-thread-5..4
Thread entering into waiting state : pool-1-thread-8 for Object this : ObjectPool@7bedda88
Thread entering into waiting state : pool-1-thread-6 for Object this : ObjectPool@43cdad4b
Thread entering into waiting state : pool-1-thread-7 for Object this : ObjectPool@5e990133
Thread Giving Notification : pool-1-thread-3..2
Thread Giving Notification : pool-1-thread-5..4
Thread Giving Notification : pool-1-thread-1..1
Thread Giving Notification : pool-1-thread-2..3
  • 当你想同步多个线程时,你应该同步 它们在 同一对象 上,而不是在 this.

  • while循环中要使用wait方法,例如:

    while (unlocked.size() == 0) {
        System.out.println("Thread entering into waiting state : "+Thread.currentThread().getName()+" for Object this : "+this.toString());
        this.getClass().wait();
    }
    

这段代码在我的机器上运行良好,试试吧

import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class ObjectPool implements Callable {

    public static ConcurrentLinkedQueue<Integer> locked = new ConcurrentLinkedQueue<>();
    public static ConcurrentLinkedQueue<Integer> unlocked = new ConcurrentLinkedQueue<>();

    static {
        int one = 1;
        int two = 2;
        int three = 3;
        int four = 4;
        unlocked.add(one);
        unlocked.add(two);
        unlocked.add(three);
        unlocked.add(four);
    }

    public Object get() throws InterruptedException {
        synchronized (getClass()) {
            while (unlocked.size() == 0) {
                System.out.println("Thread entering into waiting state : "+Thread.currentThread().getName()+" for Object this : "+this.toString());
                this.getClass().wait();
            }
            Integer i =  unlocked.poll();
            locked.add(i);
            return i;
        }
    }

    public void leave() {
        synchronized (getClass()) {
            Integer left =  locked.poll();
            unlocked.add(left);
            this.getClass().notifyAll();
        }
    }

    @Override
    public Object call() throws Exception {
        Object o1 = get();
        System.out.println("Thread going to sleep after getting lock : " + Thread.currentThread().getName() + ".." + o1.toString());
        Thread.sleep(5000);
        System.out.println("Thread Giving Notification : " + Thread.currentThread().getName() + ".." + o1.toString());
        leave();
        return o1;
    }
}

public class Driver {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        System.out.println(" Main method");

        ObjectPool[] op = {new ObjectPool(), new ObjectPool(), new ObjectPool(), new ObjectPool(), new ObjectPool(), new ObjectPool(), new ObjectPool(), new ObjectPool()};

        ExecutorService es = Executors.newFixedThreadPool(8);

        for (ObjectPool o : op) {
            es.submit(o);
        }
    }
}

输出:

Main method
Thread going to sleep after getting lock : pool-1-thread-3..4
Thread going to sleep after getting lock : pool-1-thread-1..1
Thread going to sleep after getting lock : pool-1-thread-5..2
Thread entering into waiting state : pool-1-thread-8 for Object this : hello.ObjectPool@62b3e25e
Thread entering into waiting state : pool-1-thread-6 for Object this : hello.ObjectPool@5b14447a
Thread entering into waiting state : pool-1-thread-2 for Object this : hello.ObjectPool@766f2b2c
Thread entering into waiting state : pool-1-thread-7 for Object this : hello.ObjectPool@3d804bcd
Thread going to sleep after getting lock : pool-1-thread-4..3
Thread Giving Notification : pool-1-thread-3..4
Thread going to sleep after getting lock : pool-1-thread-8..1
Thread entering into waiting state : pool-1-thread-7 for Object this : hello.ObjectPool@3d804bcd
Thread Giving Notification : pool-1-thread-1..1
Thread Giving Notification : pool-1-thread-5..2
Thread entering into waiting state : pool-1-thread-2 for Object this : hello.ObjectPool@766f2b2c
Thread entering into waiting state : pool-1-thread-6 for Object this : hello.ObjectPool@5b14447a
Thread going to sleep after getting lock : pool-1-thread-6..2
Thread entering into waiting state : pool-1-thread-7 for Object this : hello.ObjectPool@3d804bcd
Thread going to sleep after getting lock : pool-1-thread-2..3
Thread Giving Notification : pool-1-thread-4..3
Thread going to sleep after getting lock : pool-1-thread-7..4
Thread Giving Notification : pool-1-thread-8..1
Thread Giving Notification : pool-1-thread-2..3
Thread Giving Notification : pool-1-thread-6..2
Thread Giving Notification : pool-1-thread-7..4