何靖的博客


  • 首页

  • 标签

  • 分类

  • 归档

  • 搜索

多线程`同步`有几种方式

发表于 2019-03-08 | 分类于 Java , 多线程

1、使用synchronized(可同步代码片段也可同步整个函数)

  • synchronized关键字修饰的方法。
    由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,
    内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。
    即有synchronized关键字修饰的方法。
    由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,
    内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。

代码如:

1
2
public synchronized void test(){
}

注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类

  • synchronized同步代码块
    即有synchronized关键字修饰的语句块。
    被该关键字修饰的语句块会自动被加上内置锁,从而实现同步

代码如:

1
2
synchronized(object){ 
}

注:同步是一种高开销的操作,因此应该尽量减少同步的内容。
通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。

2、使用重入锁实现线程同步

在JavaSE5.0中新增了一个java.util.concurrent包来支持同步。
ReentrantLock类是可重入、互斥、实现了Lock接口的锁,
它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力。
ReenreantLock类的常用方法有:

  • ReentrantLock() : 创建一个ReentrantLock实例
  • lock() : 获得锁
  • *unlock() *: 释放锁
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class Bank {

    private int account = 100;
    //需要声明这个锁
    private Lock lock = new ReentrantLock();
    public int getAccount() {
    return account;
    }
    //这里不再需要synchronized
    public void save(int money) {
    lock.lock();
    try{
    account += money;
    }finally{
    lock.unlock();
    }
    }
    }

注:关于Lock对象和synchronized关键字的选择:
a.最好两个都不用,使用一种java.util.concurrent包提供的机制,
能够帮助用户处理所有与锁相关的代码。
b.如果synchronized关键字能满足用户的需求,就用synchronized,因为它能简化代码
c.如果需要更高级的功能,就用ReentrantLock类,此时要注意及时释放锁,否则会出现死锁,通常在finally代码释放锁

类加载机制之验证

发表于 2019-03-08 | 分类于 Java

原文链接:https://blog.csdn.net/ns_code/article/details/17881581

目的

验证的目的是为了确保Class文件中的字节流包含的信息符合当前虚拟机的要求,而且不会危害虚拟机自身的安全。

目标

不同的虚拟机对类验证的实现可能会有所不同,但大致都会完成以下四个阶段的验证:文件格式的验证、元数据的验证、字节码验证和符号引用验证。

  • 文件格式的验证:验证字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理,该验证的主要目的是保证输入的字节流能正确地解析并存储于方法区之内。经过该阶段的验证后,字节流才会进入内存的方法区中进行存储,后面的三个验证都是基于方法区的存储结构进行的。

  • 元数据验证:对类的元数据信息进行语义校验(其实就是对类中的各数据类型进行语法校验),保证不存在不符合Java语法规范的元数据信息。

  • 字节码验证:该阶段验证的主要工作是进行数据流和控制流分析,对类的方法体进行校验分析,以保证被校验的类的方法在运行时不会做出危害虚拟机安全的行为。

  • 符号引用验证:这是最后一个阶段的验证,它发生在虚拟机将符号引用转化为直接引用的时候(解析阶段中发生该转化,后面会有讲解),主要是对类自身以外的信息(常量池中的各种符号引用)进行匹配性的校验。

单例模式

发表于 2019-03-08 | 分类于 设计模式

本文摘自维基百科

单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。
—— 维基百科

实现单例模式的思路:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。

通常单例模式在Java语言中,有两种构建方式:

  • 懒汉方式:指全局的单例实例在第一次被使用时构建。
  • 饿汉方式:指全局的单例实例在类装载时构建。

Java
在Java语言中,单例模式(饿汉模式)应用的例子如下述代码所示:

1
2
3
4
5
6
7
8
9
10
11
public class Singleton {
private final static Singleton INSTANCE = new Singleton();

// Private constructor suppresses
private Singleton() {}

// default public constructor
public static Singleton getInstance() {
return INSTANCE;
}
}

在Java编程语言中,单例模式(懒汉模式)应用的例子如下述代码所示 (此种方法只能用在JDK5及以后版本(注意 INSTANCE 被声明为 volatile),之前的版本使用“双重检查锁”会发生非预期行为[1]):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

public class Singleton {
private static volatile Singleton INSTANCE = null;

// Private constructor suppresses
// default public constructor
private Singleton() {}

//thread safe and performance promote
public static Singleton getInstance() {
if(INSTANCE == null){
synchronized(Singleton.class){
//when more than two threads run into the first null check same time, to avoid instanced more than one time, it needs to be checked again.
if(INSTANCE == null){
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
1…34
何靖

何靖

18 日志
13 分类
28 标签
GitHub E-Mail CSDN
© 2021 何靖
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4