JAVA多线程单例模式及死锁

本文深入探讨了多线程的创建方式、线程状态、同步机制、单例模式及死锁现象,提供了丰富的代码示例,帮助读者理解多线程编程的关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


    上一篇我总结了创建多线程的两种方式(继承Thread类与实现Runnable接口),及多线程的不安全性,及解决多线程不安全的两种方式(同步代码块和同步函数)。


    现在开始总结多线程的几种状态。



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();
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值