Object中的wait、notify、notifyAll,以及基于此方法实现生产者消费者模式

一:Object是所有类的父类,即我们写的所有类都默认继承了此类,所有对象包括数组都实现了该类的方法;那么此类的方法是都应该有所了解的

下图给出JDK10中Object类的方法:

1.hashCode()方法

  对象之间常用到equals方法,当对比两个对象的时候,通过hash生成一个对象的hash码,如果hash码相同,那么两个对象可能相同,如果hash码不同,那么两个对象肯定不同,可以增加对象对比的效率,一般对象在重写了equals方法都需要覆写此方法;这个方法在一些具有哈希功能的Collection中用到;

2.equals()方法

  该方法是非常重要的一个方法。一般equals和==是不一样的,但是在Object中两者是一样的。子类一般都要重写这个方法。此处给出String的重写equals方法的例子

  

3. clone()方法

  实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。此处没有什么好说的,直接上代码:

  

@Slf4j
public class TestObjectClone implements Cloneable {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    protected TestObjectClone clone() throws CloneNotSupportedException {
        return (TestObjectClone) super.clone();
    }

    public static void main(String[] args) {
        TestObjectClone testObjectClone = new TestObjectClone();
        testObjectClone.setName("java");
        testObjectClone.setAge(23);
        TestObjectClone testObjectClone2;
        try {
            testObjectClone2 = testObjectClone.clone();
            log.info("名称是{},年龄是{}", testObjectClone2.getName(), testObjectClone2.getAge());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

4. toString()方法 

  此方法常用方法;

5.notify()方法

  法唤醒在该对象上等待的某个线程

6.wait()方法

  使当前线程等待该对象的锁,当时当前线程必须持有该对象的锁,同时在执行wait方法是当前线程会自动释放掉该对象锁,单该线程会一直阻塞在wait方法,知道一下事件被唤醒:

  (1)其他线程调用了该对象的notify方法。

  (2)其他线程调用了该对象的notifyAll方法。

  (3)其他线程调用了interrupt中断该线程。

  (4)时间间隔到了。

7.notifyAll() 唤醒该对象的所有线程;

8.wait(long timeOut) 该线程睡眠,多久后自动唤醒

 

二:基于wait()和notifyAll()实现生产者消费者模式

  生产者:

@Slf4j
public class Consumers implements Runnable {
private BlockingQueue<String> queue;
/**
* 工作效率
*/
private long millis;

public Consumers(BlockingQueue<String> queue, long millis) {
this.queue = queue;
this.millis = millis;
}

@Override
public void run() {
while (true) {
try {
Thread.sleep(millis);
String str = queue.take();
if (StringUtils.isNullOrEmpty(str)) {
synchronized (queue) {
queue.wait();
}
} else {
synchronized (queue) {
queue.remove(0);
queue.notifyAll();
log.info("消费者消费消息:{}", str);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}

  消费者

@Slf4j
public class Producers implements Runnable {
    private BlockingQueue<String> queue;
    private long millis;
    private static AtomicInteger atomicInteger = new AtomicInteger(0);

    public Producers(BlockingQueue<String> queue, long millis) {
        this.queue = queue;
        this.millis = millis;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(millis);
                synchronized (queue) {
                    if (queue.size() >= 100) {
                        queue.wait();
                    }
                    int news = atomicInteger.incrementAndGet();
                    if (queue.offer("生产者生产消息" + news)) {
                        log.info("新增消息:{}", news);
                        queue.notifyAll();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

  入口方法:

public class Main {
    private static final ExecutorService executorService = ThreadPoolInstance.getThreadPollInstance(5, 200, 0L);

    public static void main(String[] args) {
        BlockingQueue<String> queue = new LinkedBlockingDeque<>(100);
        Producers producers = new Producers(queue, 10);
        Consumers consumers = new Consumers(queue, 20);
        executorService.execute(producers);
        executorService.execute(consumers);
    }
}

  运行结果:

11:10:18.137 [zl_pool-0] INFO com.zl.concurrency.example.object.waitnotify.Producers - 新增消息:1
11:10:18.152 [zl_pool-1] INFO com.zl.concurrency.example.object.waitnotify.Consumers - 消费者消费消息:生产者生产消息1
11:10:18.153 [zl_pool-0] INFO com.zl.concurrency.example.object.waitnotify.Producers - 新增消息:2
11:10:18.164 [zl_pool-0] INFO com.zl.concurrency.example.object.waitnotify.Producers - 新增消息:3
11:10:18.173 [zl_pool-1] INFO com.zl.concurrency.example.object.waitnotify.Consumers - 消费者消费消息:生产者生产消息2
11:10:18.175 [zl_pool-0] INFO com.zl.concurrency.example.object.waitnotify.Producers - 新增消息:4
11:10:18.186 [zl_pool-0] INFO com.zl.concurrency.example.object.waitnotify.Producers - 新增消息:5
11:10:18.194 [zl_pool-1] INFO com.zl.concurrency.example.object.waitnotify.Consumers - 消费者消费消息:生产者生产消息3
11:10:18.197 [zl_pool-0] INFO com.zl.concurrency.example.object.waitnotify.Producers - 新增消息:6
11:10:18.208 [zl_pool-0] INFO com.zl.concurrency.example.object.waitnotify.Producers - 新增消息:7
11:10:18.215 [zl_pool-1] INFO com.zl.concurrency.example.object.waitnotify.Consumers - 消费者消费消息:生产者生产消息4
.........................................
11:10:24.680 [zl_pool-0] INFO com.zl.concurrency.example.object.waitnotify.Producers - 新增消息:412
11:10:24.701 [zl_pool-1] INFO com.zl.concurrency.example.object.waitnotify.Consumers - 消费者消费消息:生产者生产消息313
11:10:24.701 [zl_pool-0] INFO com.zl.concurrency.example.object.waitnotify.Producers - 新增消息:413
11:10:24.722 [zl_pool-1] INFO com.zl.concurrency.example.object.waitnotify.Consumers - 消费者消费消息:生产者生产消息314
11:10:24.722 [zl_pool-0] INFO com.zl.concurrency.example.object.waitnotify.Producers - 新增消息:414
11:10:24.743 [zl_pool-1] INFO com.zl.concurrency.example.object.waitnotify.Consumers - 消费者消费消息:生产者生产消息315
11:10:24.743 [zl_pool-0] INFO com.zl.concurrency.example.object.waitnotify.Producers - 新增消息:415
11:10:24.764 [zl_pool-1] INFO com.zl.concurrency.example.object.waitnotify.Consumers - 消费者消费消息:生产者生产消息316
11:10:24.764 [zl_pool-0] INFO com.zl.concurrency.example.object.waitnotify.Producers - 新增消息:416

  结果分析:此处设置的生产者是10毫秒生产一个消息,消费者是20毫秒消费一个消息,队列长度是100,当队列满的时候停止生产,当队列为空的时候停止消费;所以开始时候,生产者效率大于消费者效率,当队列满了之后,会达到一个平衡;

具体模型如下:

 

posted @ 2018-12-07 11:16  zlAdmin  阅读(814)  评论(0编辑  收藏  举报