0
点赞
收藏
分享

微信扫一扫

Java多线程学习笔记 - Java多线程中的死锁

三次方 2022-04-04 阅读 52

1、java对象的锁

        java中的每个对象都有一个唯一的锁。在任何时刻,最多只允许一个线程拥有这把锁。当我们使用synchronized关键字时,锁的概念就会出现。 

2、死锁示例

        下面是容易出现死锁的示例参考代码,不建议使用在线 IDE 运行上述程序。建议使用javac命令编译之后使用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();
		System.out.println("test1-end");
	}

	// second synchronized method
	synchronized void test2()
	{
		System.out.println("test2-begin");
		Util.sleep(1000);
		// taking object lock of s1 enters
		// into test1 method
		System.out.println("test2-end");
	}
}


class Thread1 extends Thread
{
	private Shared s1;
	private Shared s2;

	// constructor to initialize fields
	public Thread1(Shared s1, Shared s2)
	{
		this.s1 = s1;
		this.s2 = s2;
	}

	// run method to start a thread
	@Override
	public void run()
	{
		// taking object lock of s1 enters
		// into test1 method
		s1.test1(s2);
	}
}


class Thread2 extends Thread
{
	private Shared s1;
	private Shared s2;

	// constructor to initialize fields
	public Thread2(Shared s1, Shared s2)
	{
		this.s1 = s1;
		this.s2 = s2;
	}

	// run method to start a thread
	@Override
	public void run()
	{
		// taking object lock of s2
		// enters into test2 method
		s2.test1(s1);
	}
}


public class Deadlock
{
	public static void main(String[] args)
	{
		// creating one object
		Shared s1 = new Shared();

		// creating second object
		Shared s2 = new Shared();

		// creating first thread and starting it
		Thread1 t1 = new Thread1(s1, s2);
		t1.start();

		// creating second thread and starting it
		Thread2 t2 = new Thread2(s1, s2);
		t2.start();

		// sleeping main thread
		Util.sleep(2000);
	}
}

        上面代码进行了那些操作?

3、查看死锁

        在运行上一小节的代码之后,出现死锁时可以进入windows详细信息,可以看到两个java线程在运行。

         我们可以再启动一个cmd窗口,运行jcmd $PID Thread.print命令其中$PID是上图中的线程id。

        我这里输入jcmd 53364 Thread.print之后回车,会看到输出明确说明发现一个死锁。

 4、避免死锁

        避免嵌套锁:这是死锁的主要原因。死锁主要发生在我们给多个线程加锁时。如果我们已经给了一个线程,请避免给多个线程加锁。

        避免不必要的锁:我们应该只锁定那些需要的成员。不必要的锁定会导致死锁。

        使用join:当一个线程正在等待另一个线程完成时出现死锁情况。如果发生这种情况,我们可以使用 Thread.join 以及您认为执行所需的最长时间。

举报

相关推荐

0 条评论