对象池通知不起作用

时间:2018-04-22 15:50:33

标签: java multithreading wait notify object-pooling

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

我在这里面临的问题是,在离开对象并调用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

1 个答案:

答案 0 :(得分:1)

  • 如果要同步多个线程,则应进行同步 他们在同一个对象上,而不是这个

  • 应在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