JAVA 0827 day22 Vimcelia总结

总结

今天主要还是巩固了多线程的相关知识,了解到线程的生命周期,多线程运行的第三种方式-----线程池,生产者与消费者模式,单例设计模式和简单工厂者模式以及枚举类型是相关内容。

线程的生命周期在这里插入图片描述

NEW 新建态

至今尚未启动的线程处于这种状态。

RUNNABLE 就绪态和运行态

正在 Java 虚拟机中执行的线程处于这种状态。

BLOCKED 阻塞态(等待锁和I\O)

受阻塞并等待某个监视器锁的线程处于这种状态。

WAITING 阻塞态1(调用了wait方法,等待其他线程唤醒的状态)

无限期地等待另一个线程来执行某一特定操作的线程处于这种状态。

TIMED_WAITING 阻塞态2(调用了用时间限制的wait方法或者是sleep方法)

等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态。

TERMINATED 死亡态

已退出的线程处于这种状态。

public Thread.State getState( )   //获取线程的状态 

线程池

步骤:

  1. 创建一个实现类实现接口Callable;
  2. 实现Callable里面的run( )方法(此方式的run方法有返回值);
  3. 实例化一个ExecutorService得到线程池的对象;

语法:

ExecutorService  es = Executors.newFixedThreadPool(线程数量)//得到线程池的对象
  1. 使用这个对象调用实现类里面重写的run方法;
  2. 实例化一个Futrue对象接受run方法的返回值;(这个过程叫做异步回调)
  3. 使用shutdown()结束这个线程;

生产者与消费者模式

生产者与消费者模式的实际问题是指两个线程不能同时进行,一个线程正在运行另外一个线程必须等待资源;要实现这样的操作必须使用同步锁(对象锁)

需要使用的几种方法
  1. Object里面的方法:
  • wait( ) 等待线程(可以传参也可以不传参)
  • notify()唤醒当前睡眠的线程
  • notifyall()唤醒所有睡眠的线程
    是Object方法的原因:这些方法都依赖于对象锁,对象是任意的对象,能够表示任意的对象的类只有Object
  1. wait( ) 与 sleep() 的区别 sleep() 在一段时间会释放锁 , wait()可以一段时间类释放锁,也可以永久不释放;
  2. 在这里插入图片描述
  3. notify() 与 notifyAll( ) 的区别 : notify 唤醒当前睡眠的对象,如果这个睡眠对象有多个,会交替的唤醒;notifyAll 唤醒所有睡眠的线程
		public class demo {
        //肯定要有一个产品类(内部类)
        static  class Product{
            //定义一个变量来记录产品的信息
            //volatile 这个关键字的作用是 ,
            //也就是a线程的数据发生改变,b线程可以立马知道
            public   static  volatile  String values;
        }
        //定义一个生产者的类,实现多线程
        static  class  Producter extends Thread{
            // 定义一个产品
            Object  lock;
            public  Producter (Object lock){
                this.lock =lock;
            }
            @Override
            public void run() {
                // 如果不为空,代表有产品,思考,能保证消费者与生产者的线程只有一个执行, 也就是要加锁
                while(true){
                    synchronized (lock) {
                        if(Product.values  !=null){
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            //当前线程阻塞
                            //wait();
                        }
                        //生产产品(什么情况下生产产品)
                        Product.values="生产者生产的产品是:"+System.currentTimeMillis();
                        System.out.println(Product.values);
                        // 通知消费者进行消费(换醒其它线程)
                        lock.notify();
                    }
                }
            }
        }
        //消费者

        static class Customer extends Thread{
            // 也要提供一个产品进行操作
            Object  lock;
            public  Customer(Object  lock){
                this.lock = lock;
            }
            @Override
            public void run() {
                //关键点  消费产品(什么时候进行消费)
                while(true){
                    synchronized (lock) {
                        if(Product.values ==null){
                            // 线程阻塞
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }

                        // 不同于同null 消费
                        System.out.println("当前消费的产品是"+Product.values);
                        //消费完成之后,把产品设置为null
                        Product.values=null;
                        //  通知生产者进行生产
                        lock.notify();

                    }
                }

            }


        }

        //  这样就保证线程a 执行一次 ,  线程b  执行了一次
        public static void main(String[] args) {
            Object  object   = new Object();
            // 首先生产产品
            new Producter(object).start();

            // 调用消费者的线程
            new Customer(object).start();

        }

    }

延时操作模式

public void schedule(TimerTask task, long delay, long period)

第一个参数传递了一个任务对象;第二个参数是隔多少秒来执行这个操作;第三个参数是每次间隔发送的时间(时间是以毫秒值为单位)
同时可以传递Date对象进行操作

TimerTask 这个是定时操作的任务对象

单例设计模式

设计模式 :

开发大佬,给的一些好的经验抽取

单例设置模式 :

有且仅加载一个类, 静态的也可以有且仅加载一次(出现问题比较多)

单例设计模式 :

只要是这个类在内存里只加载一次, 工具类大部分情况都是的是单例设计模式

单例设计模式的三个要素:
  1. 私有的属性 这个属性是当前类( 外部不能来访问这个属性)
  2. 私有的构造 不让外部来实例化这个类,使用私有的构造
  3. 公有的方法 : 提供一个对外的方法,让别人进行访问
各种模式
1. 恶汉模式 :

一开始就实例化出来 ,缺点超级多 :运行就卡 优点 :线程安全

private    DateFormatUtils  utils  = new   DateFormatUtils()
private    DateFormatUtils(){
	 }
// 对外的方法
    public    DateFormatUtils    getInstance(){
                  return   utils
                      }
2. 懒汉 (比较懒)

懒加载 :不是一开始就加载 ,而是用的时候去加载
性能有所优化, 线程不安全

public class StringUtils {
  // 私有的属性
private  static   StringUtils stringUtils;
  //私有的构造
private   StringUtils(){
  }
 // 在方法上加锁
public  synchronized    StringUtils   getInstance(){
       // 做一个判断是null判断
         if(stringUtils ==null){
             // 才实例化
              stringUtils = new StringUtils();
         }
         return    stringUtils;
  }
3.老汉模式

不能被修改 ==> private final DateFormatUtils utils = new DateFormatUtils()

4.双重锁
public class FileUtils {
 // 私有的属性
  private  static   FileUtils fileUtils;
    // 私有的构造
  private   FileUtils(){
  }
  // 提供公有的方法
   public   synchronized static  FileUtils   getInstance(){
       if(fileUtils ==null){
           //锁class 文件,防止高并发里遇到实例化两个对象,锁class文件
            synchronized (FileUtils.class){
                 if(fileUtils == null){
                      fileUtils  = new FileUtils();
                 }
            }
       }
        return   fileUtils;
   }
}

简单工厂

简单工厂者模式:
生产产品 (对象) ==> 就是多态的一种体现
体现形式:

  1. 以父类作为返回值
    工厂类
    在这里插入图片描述
  2. 以父类作为参数
    工厂接口
    在这里插入图片描述在这里插入图片描述

枚举类型

枚举类 :枚举类里都是常量

  • 定义枚举的产量的时候 一般都是大写
  • 每一个常量都是以逗号进行分割
定义:

是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内.

使用格式:

枚举类型通过enum语句来定义。

public enum Week {
	MON("星期一"),
	TUE("星期二"),
	WED("星期三"),
	THR("星期四"),
	FRI("星期五"),
	SAT("星期六"),
	SUN("星期日");
	private String day;

	Week(String day) {
    	this.day = day;
	}

	public String getDay() {
    	return day;
	}

	public void setDay(String day) {
    	this.day = day;
	}
}

返回此枚举常量的名称,在其枚举声明中对其进行声明。

public final String name()

返回带指定名称的指定枚举类型的枚举常量。名称必须与在此类型中声明枚举常量所用的标识符完全匹配。

public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name)

返回枚举常量的名称,它包含在声明中。

public String toString()

疑问

简单工厂者模式为什么一点都不感觉简单,反而觉得代码量十分大,在什么时候应用简单工厂者模式才是对的?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值