Java22--多线程2(同步锁+ 单例设计模式)

1 同步锁

把有可能出现问题的代码包起来,一次只让一个线程执行。通过sychronized关键字实现同步。

当多个对象操作共享数据时,可以使用同步锁解决线程安全问题。

1.1 synchronized

synchronized(对象){

    需要同步的代码;

}

1.2 特点

1、 前提1,同步需要两个或者两个以上的线程。

2、 前提2,多个线程间必须使用同一个锁。

3、 同步的缺点是会降低程序的执行效率, 为了保证线程安全,必须牺牲性能。

4、 可以修饰方法称为同步方法,使用的锁对象是this。

5、 可以修饰代码块称为同步代码块,锁对象可以任意。

1.3 改造

package seday13new;

 

public class Test4 {

    public static void main(String[] args) {

       Ticket2 t = new Ticket2();

       Thread target = new Thread(t, "窗口1");

       Thread target2 = new Thread(t, "窗口2");

       Thread target3 = new Thread(t, "窗口3");

       Thread target4 = new Thread(t, "窗口4");

target.start();

target2.start();

       target3.start();

target4.start();

    }

}

 

class Ticket2 implements Runnable {

 

private int tic = 100;

    Object obj = new Object();

 

    @Override

    public void run() {

       while (true) {

           // 把有线程安全问题的代码,用同步关键字包起来

           // 原理:用一个对象作为一把锁,给代码上锁,一个线程访问锁代码时,其他线程只能等待锁释放才能进来。

           // 多线程间要使用同一把锁才可以真的把代码锁住实现线程安全。  

// synchronized (new Object()) {//锁了不同对象

           // synchronized (obj) {//锁了同一个对象

//synchronized (Ticket2.class) {//锁了本类,针对于静态

           synchronized (this) {

              if (tic > 0) {

                  try {

                     Thread.sleep(100);

                  } catch (InterruptedException e) {

                     e.printStackTrace();

                  }

                  System.out.println(tic--);

              }

           }

       }

 

    }

}

2 单例设计模式

2.1 概念

单例模式可以说是大多数开发人员在实际中使用最多的,常见的Spring默认创建的bean就是单例模式的。

单例模式有很多好处,比如可节约系统内存空间,控制资源的使用。

其中单例模式最重要的是确保对象只有一个。

简单来说,保证一个类在内存中的对象就一个。

RunTime就是典型的单例设计,我们通过对RunTime类的分析,一窥究竟。

2.2 源码剖析

/**

 * Every Java application has a single instance of class

 * <code>Runtime</code> that allows the application to interface with

 * the environment in which the application is running. The current

 * runtime can be obtained from the <code>getRuntime</code> method.

 * <p>

 * An application cannot create its own instance of this class.

 *

 * @author  unascribed

 * @see     java.lang.Runtime#getRuntime()

 * @since   JDK1.0

 */

RunTime.java

package java.lang;

 

public class Runtime {

    //1、创建静态的全局唯一的对象

    private static Runtime currentRuntime = new Runtime();

 

    //2、私有构造方法,不让外部来调用

    /** Don't let anyone else instantiate this class */

    private Runtime() {}

 

    //3、通过自定义的静态方法获取实例

    public static Runtime getRuntime() {

        return currentRuntime;

    }

}

2.3 饿汉式

package cn.tedu.design;

//测试单例设计模式--就是按照一定的开发步骤,按照一定的模板进行开发,达到程序中只会有一个实例在干活的目的!!

public class Test5_Design {

    public static void main(String[] args) {

       //4,测试 new多少次都是一个对象???--

//     MySingleTon m = new MySingleTon();--构造方法私有化

       MySingleTon m1 = MySingleTon.getMy();

       MySingleTon m2 = MySingleTon.getMy();

       System.out.println(m1==m2);//是同一个对象吗???

       System.out.println(m1.equals(m2));//默认用Object的==

    }

}

class MySingleTon {

    //1,私有化改造方法  -- 目的就是控制外界创建对象的权利

    private MySingleTon() {}

    //2,封装创建好的对象   -- 封装,不让外界随意看到我创建的对象

    static private MySingleTon my = new MySingleTon();

    //3,提供公的获取对象的方法

    //静态方法,因为没法new了,还想用,就用类名访问--修饰成静态的

    static public MySingleTon getMy(){

       return my;//静态只能调静态

    }

}

2.4 懒汉式

//懒汉式 -- 面试重点!!延迟加载思想+线程不安全

class MySingleTon2 {

    // 1,私有化改造方法 -- 目的就是控制外界创建对象的权利

    private MySingleTon2() {

    }

    // 2,封装创建好的对象 -- 先不创建对象,啥时候用啥时候创建!!

    static private MySingleTon2 my;

    // 3,提供公的获取对象的方法

    // 静态方法,因为没法new了,还想用,就用类名访问--修饰成静态的

    synchronized static public MySingleTon2 getMy() {//b,方法里都是同步代码,可以是同步方法

//     synchronized (MySingleTon2.class) {//a,同步代码块,静态方法的锁,是类名.class本类的字节码对象

           // t1,t2,t3来准备new

           if (my == null) {

              // t1 new

              // t2 new

              // t3 new

              my = new MySingleTon2();// 开始创建!! 延迟加载

           }

//     }

       return my;// 静态只能调静态

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值