java中多线程情况下如何解锁线程

java中多线程情况下如何解锁线程,java,multithreading,Java,Multithreading,在业务流程的某个地方,我的线程被锁定。所以在那之后,一切都将处于等待状态。如果是这样的话,那么如何在不挂起应用程序的情况下继续操作呢。 这意味着我不想终止申请。实际上这是一个面试问题 首先,也是最重要的,强烈建议大家好好阅读维基百科条目。特别是关于 如果这是一个面试问题,面试官可能更感兴趣的是应聘者对僵局如何发生以及如何防止和/或解决僵局的了解 下面是一个在一组对象上使用via同步创建java死锁的基本示例 private static void synchronizedBlockDeadloc

在业务流程的某个地方,我的线程被锁定。所以在那之后,一切都将处于等待状态。如果是这样的话,那么如何在不挂起应用程序的情况下继续操作呢。
这意味着我不想终止申请。实际上这是一个面试问题

首先,也是最重要的,强烈建议大家好好阅读维基百科条目。特别是关于

如果这是一个面试问题,面试官可能更感兴趣的是应聘者对僵局如何发生以及如何防止和/或解决僵局的了解

下面是一个在一组对象上使用via同步创建java死锁的基本示例

private static void synchronizedBlockDeadlock()
{
    final Object resource1 = new Object();
    final Object resource2 = new Object();

    Runnable thread1 = new Runnable()
    {

        public void run()
        {
            synchronized (resource1)
            {
                final int sleepTimeMs = 1000;
                try
                {
                    Thread.sleep(sleepTimeMs);
                }
                catch (InterruptedException e) {}

                synchronized (resource2)
                {
                    System.out.println("In thread1");
                }
            }
        }
    };

    Runnable thread2 = new Runnable()
    {

        public void run()
        {
            synchronized (resource2)
            {
                final int sleepTimeMs = 1000;
                try
                {
                    Thread.sleep(sleepTimeMs);
                }
                catch (InterruptedException e) {}

                synchronized (resource1)
                {
                    System.out.println("In thread2");
                }
            }
        }
    };

    new Thread(thread1).start();
    new Thread(thread2).start();
}
首先,两个线程有效地同时运行。线程1将获得对资源1的锁并休眠片刻,使线程2能够获得对资源2的锁。当然,这是基于线程2能够在线程1中的睡眠调用返回之前启动的假设。现在,线程2尝试获取由线程1持有的资源1上的锁,因此它会无限期地阻塞。线程1唤醒并尝试获取由线程2持有的资源2上的锁。两个线程在另一个线程上被阻塞,因此所有线程都处于死锁状态

现在,可以重新编写此代码,使用显式锁来防止死锁,而不是通过'synchronized'关键字对资源对象实例使用隐式锁

请参阅下面的代码:

private static void explicitLockDeadlock()
{
    final Lock lock1 = new ReentrantLock();
    final Lock lock2 = new ReentrantLock();

    Runnable thread1 = new Runnable()
    {

        public void run()
        {
            try
            {
                lock1.tryLock(5, TimeUnit.SECONDS);
                System.out.println("Thread-1: Lock 1 acquired");

                final int sleepTimeMs = 1000;
                Thread.sleep(sleepTimeMs);

                lock2.tryLock(5, TimeUnit.SECONDS);
                System.out.println("Thread-1: Lock 2 acquired");
            }
            catch (InterruptedException e) {}
            finally
            {
                lock1.unlock();
            }

            System.out.println("In thread1");
        }
    };

    Runnable thread2 = new Runnable()
    {

        public void run()
        {
            try
            {
                lock2.tryLock(5, TimeUnit.SECONDS);
                System.out.println("Thread-2: Lock 2 acquired");

                lock1.tryLock(5, TimeUnit.SECONDS);
                System.out.println("Thread-2: Lock 1 acquired");
            }
            catch (InterruptedException e) {}
            finally
            {
                lock2.unlock();
            }

            System.out.println("In thread2");
        }
    };

    new Thread(thread1).start();
    new Thread(thread2).start();
}

这种方法是抢占一个可能死锁的线程的实例,或者打破4的“无抢占”条件。实际上,等待的“tryLock”调用在指定的时间段后过期,从而防止应用程序无限期挂起。

使用jps或任务管理器获取进程ID,然后使用jstack-F获取所有线程的堆栈跟踪和锁信息,包括一些关于检测到的死锁的提示。

事实上,我对此不太清楚。你能简单地解释一下吗?在Windows上,我不知道怎么做;在Unix系统上,向JVM的PID发送一个USR1信号,它将在stderr上输出一个线程转储。windows上的任何一个plz都可以指导它如何工作使用jps获取Java PID,使用jstack${PID}获取线程转储使用jconsole。启动命令窗口并输入jconsole。如果您安装了JDK,那么它将启动您需要的工具,以便深入到正在运行的JVM中。您将能够逐个检查线程的状态。