我是靠谱客的博主 飞快路人,最近开发中收集的这篇文章主要介绍Java 各种设计模式 持续更新一、生产者和消费者模式二、单例模式,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、生产者和消费者模式

关于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 各种设计模式 持续更新一、生产者和消费者模式二、单例模式所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部