Java 多线程
synchronized关键字用于使类或方法线程安全,这意味着只有一个线程可以锁定同步方法并使用它,其他线程必须等到锁定释放并且其中任何一个获得该锁定。
如果我们的程序在多线程环境中运行,并且两个或多个线程同时执行,则使用它非常重要。但有时它也会导致一个叫做死锁的问题。
Java中死锁的介绍
操作系统中的进程使用不同的资源并以下列方式使用资源。
1)请求资源
2)使用资源
2)释放资源
死锁是一组进程被阻塞的情况,因为每个进程都持有一个资源并等待某个其他进程获取的另一个资源。
考虑一个例子,当两列火车在同一轨道上相互靠近并且只有一条轨道时,一旦它们在彼此前面,没有一列列车可以移动。当有两个或多个进程持有某些资源并等待其他资源持有的资源时,在操作系统中会出现类似的情况。例如,在下图中,进程1保持资源1并等待由进程2获取的资源2,并且进程2正在等待资源1。
如果同时遵循四个条件,则可能出现死锁(必要条件)
相互排斥:一个或多个资源是不可共享的(一次只能使用一个进程)
保持和等待:进程至少保留一个资源并等待对于资源。
No Preemption:除非进程释放资源,否则无法从进程中获取资源。
循环等待:一组进程以循环形式相互等待。
处理死锁的方法
有三种方法可以处理死锁
1)死锁防止或避免:想法是不让系统进入死锁状态。
2)死锁检测和恢复:发生死锁,然后抢先处理它一旦发生。
3)一起忽略问题:如果死锁非常罕见,那就让它发生并重启系统。这是Windows和UNIX采用的方法。
Java死锁条件的一个简单示例
// Java program to illustrate Deadlock
// in multithreading.
class Util
{
// Util class to sleep a thread
static void sleep(long millis)
{
try
{
Thread.sleep(millis);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
// This class is shared by both threads
class Shared
{
// first synchronized method
synchronized void test1(Shared s2)
{
System.out.println("test1-begin");
Util.sleep(1000);
// taking object lock of s2 enters
// into test2 method
s2.test2(this);
System.out.println("test1-end");
}
// second synchronized method
sy