概述
一、生产者和消费者模式
关于Object类中的wait和notify方法。(生产者和消费者模式!)
第一:wait和notify方法不是线程对象的方法,是java中任何一个java对象
都有的方法,因为这两个方式是Object类中自带的。
wait方法和notify方法不是通过线程对象调用,
不是这样的:t.wait(),也不是这样的:t.notify()..不对。
第二:wait()方法作用?
Object o = new Object();
o.wait();
表示:
让正在o对象上活动的线程进入等待状态,无期限等待,
直到被唤醒为止。
o.wait();方法的调用,会让“当前线程(正在o对象上
活动的线程)”进入等待状态。
第三:notify()方法作用?
Object o = new Object();
o.notify();
表示:
唤醒正在o对象上等待的线程。
还有一个notifyAll()方法:
这个方法是唤醒o对象上处于等待的所有线程。
概念
- 1、使用wait方法和notify方法实现生产者和消费者模式
- 2、什么是生产者和消费者模式?
- 生产线程负责生产,消费现场负责消费。
- 生成线程和消费线程要达到均衡。
- 这是一种特殊的业务需求,在这种特殊的情况下需要使用wait方法和noify方法
- 3、wait和notify方法不是线程对象的方法,是普通java对象都有的方法。
- 4、wait和notify方法建立在线程同步的基础上。因为多线程要同时操作一个仓库,有线程安全问题。
- 5、wait方法作用:o.wait让正在o对象上活动的线程t进入等待状态,并且释放掉t线程之前占有的o对象的锁。
- 6、notify方法作用:o.notify()让正在o对象上等待的线程唤醒,只是通知,不会释放o对象上之前占有的锁。
- 7、模拟仓库使用list集合,假设只能存在一个。
代码示例
这里notifyall和notify都可以,比如消费者刚唤醒生产者,即使消费者又抢到了这把锁,但是会判断仓库里是否有库存,没有的话还是会进入wait。
public class ThreadTest16 {
public static void main(String[] args) {
List list
= new ArrayList();
//创建两个线程对象
Thread t1 = new Thread(new Producer(list));
Thread t2 = new Thread(new Consumer(list));
t1.setName("生产者线程");
t2.setName("消费者线程");
t1.start();
t2.start();
}
}
//生产者
class Producer implements Runnable{
//仓库
private List list;
public Producer(List list) {
this.list = list;
}
@Override
public void run() {
//使用死循环模拟一直生产
while (true){
//给仓库list对象加锁
synchronized (list){
if (list.size()>0){//大于0,说明有1个元素了
try {
list.wait();//进入等待,释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Object obj = new Object();
list.add(obj);
System.out.println(Thread.currentThread().getName() + "--->" + obj);
//唤醒消费者进行消费
list.notifyAll();
}
}
}
}
//消费者
class Consumer implements Runnable{
private List list;
public Consumer(List list) {
this.list = list;
}
@Override
public void run() {
//一直消费
while (true){
synchronized (list){
if (list.size()==0){
try {
//仓库已经空了。
//消费者线程等待,释放list锁
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//消费者进行消费
Object obj = list.remove(0);
System.out.println(Thread.currentThread().getName() + "--->" + obj);
//唤醒生产者进行生产
list.notifyAll();
}
}
}
}
二、单例模式
饿汉式
- (1)构造器私有化
- (2)自行创建,并且用静态变量保存
- (3)向外提供这个实例
- (4)强调这是一个单例,我们可以用final修改
直接创建(记住这个)
/*
饿汉式:
直接创建实例对象,不管你是否需要这个对象
*
(1)构造器私有化
*
(2)自行创建,并且用静态变量保存
*
(3)向外提供这个实例
*
(4)强调这是一个单例,我们可以用final修改
* */
public class Singleton1 {
//习惯上把常量写为大写
private static final Singleton1 INSTANCE = new Singleton1();
private Singleton1() {
}
public static Singleton1 getInstance(){
return INSTANCE;
}
}
枚举式
/*
- 枚举类型:表示该类型的对象是有限的几个
- 我们可以限定为一个,就成了单例
- 枚举类型构造器都是私有化的
- */
public enum Singleton2 {
INSTANCE
}
静态代码块
public class Singleton3 {
public static final Singleton3 INSTANCE;
static {
INSTANCE = new Singleton3();
}
private Singleton3() {
}
}
懒汉式
线程不安全模式(单线程)
public class Singleton4 {
private Singleton4(){
}
private static Singleton4 instance;
public static Singleton4 getInstance(){
if(instance == null){
instance = new Singleton4();
}
return instance;
}
}
多线程安全模式
为什么要两次判断:第一次判断:解决只有在单例没有创建时才存在线程安全问题,所以只在此时加锁。第二次判断:第一个线程进来,第二个线程等待,第一个线程创建完了,第二个不判断就又创建一次。
public class Singleton6 {
// volatile保证每次使用时,都从主存中取
private static volatile Singleton6 instance;
// 私有化构造函数
private Singleton6() {}
// 提供其他类获取实例的静态方法
public static Singleton6 getInstance() {
if (instance == null) {
// 如果实例不存在,进入同步代码块
synchronized (Singleton6.class) {
if (instance == null) {
// 如果实例在代码块中仍不存在,创建实例
instance = new Singleton6();
}
}
}
return instance;
}
}
最后
以上就是飞快路人为你收集整理的Java 各种设计模式 持续更新一、生产者和消费者模式二、单例模式的全部内容,希望文章能够帮你解决Java 各种设计模式 持续更新一、生产者和消费者模式二、单例模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复