JAVA多线程单例模式及死锁
2012-11-22 10:07
387 查看
上一篇我总结了创建多线程的两种方式(继承Thread类与实现Runnable接口),及多线程的不安全性,及解决多线程不安全的两种方式(同步代码块和同步函数)。
现在开始总结多线程的几种状态。
1 上图为线程运行的五种状态
线程被start()后,不一定马上运行,有可能进入阻塞状态,因为当前时间段CPU有可能正在运行其他线程。
Sleep()/wait()为冻结操作,线程会没有CPU的执行权。
Sleep()时间到后,会自动激活。
Notify()为唤醒线程。
就绪:具备运行资格,但没有执行权(等待CPU的执行权)
阻塞:放弃了执行资格,处于暂停状态
再来回顾一下进程中的概念,进程中有挂起,而线程中没有,进程也具备以上5中状态。
活动就绪:进程处于未被挂起的就绪状态
活动阻塞:进程处于未被挂起的阻塞状态
上面两个概念是将5种状态增加到7种状态后的称呼,此外还有静止就绪和活动就绪。
2 同步函数的锁是this
函数需要被对象调用,函数都有一个所属对象的引用,就是this,所以同步函数使用的锁是this.
3 静态同步函数的锁是Class对象
函数可以加static关键字
静态方法进内存的时候没有对象,静态对象由类调用,类进内存的时候会自动生成字节码文件对象class
4 单例设计模式
针对懒汉式进行分析,发现在多线程情况下,懒汉式会发生线程不安全。
有可能出现多个线程同时进入getInstance()语句,从而生成多个实例,达不到单例的效果。
针对这种情况可以讲方法更改为同步函数,但是因为每次都要判断锁,会影响效率,最后对懒汉式的代码做如下修改:
写同步代码块,通过双重判断的形式
这样做的好处就是减少了判断锁的动作,相对提高了性能。
5 死锁
是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。
死锁代码示例:
现在开始总结多线程的几种状态。
1 上图为线程运行的五种状态
线程被start()后,不一定马上运行,有可能进入阻塞状态,因为当前时间段CPU有可能正在运行其他线程。
Sleep()/wait()为冻结操作,线程会没有CPU的执行权。
Sleep()时间到后,会自动激活。
Notify()为唤醒线程。
就绪:具备运行资格,但没有执行权(等待CPU的执行权)
阻塞:放弃了执行资格,处于暂停状态
再来回顾一下进程中的概念,进程中有挂起,而线程中没有,进程也具备以上5中状态。
活动就绪:进程处于未被挂起的就绪状态
活动阻塞:进程处于未被挂起的阻塞状态
上面两个概念是将5种状态增加到7种状态后的称呼,此外还有静止就绪和活动就绪。
2 同步函数的锁是this
函数需要被对象调用,函数都有一个所属对象的引用,就是this,所以同步函数使用的锁是this.
3 静态同步函数的锁是Class对象
函数可以加static关键字
静态方法进内存的时候没有对象,静态对象由类调用,类进内存的时候会自动生成字节码文件对象class
4 单例设计模式
/* * 饿汉式 */ class Single { private static final Single s = new Single(); private Single() { } public static Single getInstance() { return s; } }
/* * 懒汉式 */ class Single2 { private static Single2 s = null; private Single2() { } public static Single2 getInstance() { if (s == null) { s = new Single2(); } return s; } }
针对懒汉式进行分析,发现在多线程情况下,懒汉式会发生线程不安全。
有可能出现多个线程同时进入getInstance()语句,从而生成多个实例,达不到单例的效果。
针对这种情况可以讲方法更改为同步函数,但是因为每次都要判断锁,会影响效率,最后对懒汉式的代码做如下修改:
class Single2 { private static Single2 s = null; private Single2() { } public static Single2 getInstance() { if (s == null) { synchronized (Single2.class) { if(s == null) { s = new Single2(); } } } return s; } }
写同步代码块,通过双重判断的形式
这样做的好处就是减少了判断锁的动作,相对提高了性能。
5 死锁
是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。
死锁代码示例:
class Test implements Runnable { private boolean flag; Test(boolean flag) { this.flag = flag; } public void run() { if (flag) { while (true) { synchronized (MyLock.locka) { System.out.println("if__a"); synchronized (MyLock.lockb) { System.out.println("if__b"); } } } } else { while (true) { synchronized (MyLock.lockb) { System.out.println("else__b"); synchronized (MyLock.locka) { System.out.println("else__a"); } } } } } } class MyLock { static Object locka = new Object(); static Object lockb = new Object(); } public class Test6 { public static void main(String[] args) { Test t1=new Test(true); Test t2=new Test(false); Thread c1=new Thread(t1); Thread c2=new Thread(t2); c1.start(); c2.start(); } }
相关文章推荐
- Lesson_for_java_day19--java的多线程(多线程概念、单例设计模式、死锁)
- 黑马程序员--读写字节数组,随机读写流,集合IO的思维导图,多线程部分,单例设计模式,线程和进程的概念,Java中的线程的创建方式,线程的随机性,线程的状态图,多线程操作共享数据的安全性,死锁
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
- Java基础之多线程(一)--概述、同步、死锁、单例模式
- 简单的Java1.4版synchronized多线程的死锁演示
- java多线程模式ThreadLocal原理简述及其使用详解
- 黑马程序员——java第十一、十二天:多线程(创建线程1-2、多线程同步代码、实现Runnable接口、安全死锁)
- Java线程和多线程(九)——死锁
- JAVA多线程之单例模式
- 16、Java并发性和多线程-死锁
- JAVA笔记14__多线程共享数据(同步)/ 线程死锁 / 生产者与消费者应用案例 / 线程池
- 黑马程序员——Java基础——多线程的同步、死锁和等待唤醒机制
- Java多线程编程-单例模式几种写法的错与对
- Java多线程编程模式实战指南一:Active Object模式
- java多线程第三天死锁问题
- java语言基础(93)——多线程中的死锁问题
- Java多线程--死锁
- java多线程synchronized的使用及死锁的造成和解锁