一、生产者和消费者模式
关于Object类中的wait和notify方法。(生产者和消费者模式!)
第一:wait和notify方法不是线程对象的方法,是java中任何一个java对象
复制代码
1
2
3
4都有的方法,因为这两个方式是Object类中自带的。 wait方法和notify方法不是通过线程对象调用, 不是这样的:t.wait(),也不是这样的:t.notify()..不对。
第二:wait()方法作用?
复制代码
1
2
3
4
5
6
7
8
9Object o = new Object(); o.wait(); 表示: 让正在o对象上活动的线程进入等待状态,无期限等待, 直到被唤醒为止。 o.wait();方法的调用,会让“当前线程(正在o对象上 活动的线程)”进入等待状态。
第三:notify()方法作用?
复制代码
1
2
3
4
5
6
7
8Object 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。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72public 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
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21直接创建实例对象,不管你是否需要这个对象 * (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
}
静态代码块
复制代码
1
2
3
4
5
6
7
8
9public class Singleton3 { public static final Singleton3 INSTANCE; static { INSTANCE = new Singleton3(); } private Singleton3() { } }
懒汉式
线程不安全模式(单线程)
复制代码
1
2
3
4
5
6
7
8
9
10
11
12public class Singleton4 { private Singleton4(){ } private static Singleton4 instance; public static Singleton4 getInstance(){ if(instance == null){ instance = new Singleton4(); } return instance; } }
多线程安全模式
为什么要两次判断:第一次判断:解决只有在单例没有创建时才存在线程安全问题,所以只在此时加锁。第二次判断:第一个线程进来,第二个线程等待,第一个线程创建完了,第二个不判断就又创建一次。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public 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内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复