Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 试图在两个线程之间创建死锁_Java_Multithreading_Deadlock - Fatal编程技术网

Java 试图在两个线程之间创建死锁

Java 试图在两个线程之间创建死锁,java,multithreading,deadlock,Java,Multithreading,Deadlock,用于通过在线程中访问print方法在两个线程之间创建死锁。我使用了循环屏障,以便两个线程同时启动。如果我是正确的,我的打印方法不会占用时间,因此它会被两个线程共享,不会导致死锁 import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class TWOTHREADDEADLOCLK { static int b =0; synch

用于通过在线程中访问print方法在两个线程之间创建死锁。我使用了循环屏障,以便两个线程同时启动。如果我是正确的,我的打印方法不会占用时间,因此它会被两个线程共享,不会导致死锁

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class TWOTHREADDEADLOCLK {

    static int b =0;
    synchronized static void print()
    {

        System.out.println(Thread.currentThread().getName() + "     " + b);
    }
    synchronized static int  getb()
    {
        print();
        return b;
    }

    synchronized static void updateb()
    {
        print();
        b=b+10;
    }
    public static void main(String[] args) {

        final CyclicBarrier bar = new CyclicBarrier(2);
        Thread thread1  = new Thread(new Runnable(){

            @Override
            public void run() 
            {
                try {
                    bar.await();

                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                catch ( BrokenBarrierException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName());
                while(true)
                    print();

            }

        });
        Thread thread2  = new Thread(new Runnable(){

            @Override
            public void run() 
            {try {
                bar.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName());
            while(true)
                getb();

            }

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

您不能使用单个屏障创建死锁。死锁背后的想法是(至少)有两个线程,每个线程持有不同的锁,并试图锁定另一个线程。例如,考虑这个简单的例子:

public class TwoLockRunnable implements Runnable {

    private Lock lockInConstructor;
    private Lock lockInRuntime;

    public TwoLockThread(Lock lockInConstructor, Lock lockInRuntime) {
        this.lockInConstructor = lockInConstructor;
        this.lockInRuntime = lockInRuntime;

        this.lockInConstructor.lock();
    }

    @Override
    public void run() {
        lockInRuntime.lock();

        System.out.println("After the lock in run()");
    }

    public static void main(String[] args) {
        Lock lock1 = new ReentrantLock();
        Lock lock2 = new ReentrantLock();

        TwoLockRunnable runnable1 = new TwoLockThread(lock1, lock2);
        TwoLockRunnable runnable2 = new TwoLockThread(lock2, lock1);

        new Thread(runnable1).start();
        new Thread(runnable2).start();
    }
}

第一个线程在其构造函数中锁定
lock1
,第二个线程在其构造函数中锁定
lock2
。然后,第一个线程在运行时尝试锁定
lock2
,但它无法锁定,因为锁由另一个线程持有。类似地,第二个线程在运行时尝试锁定
lock1
,但由于同样的原因失败。因此,会出现死锁,并且在锁定运行()之后的消息
不会被打印。

不能使用单个屏障创建死锁。死锁背后的想法是(至少)有两个线程,每个线程持有不同的锁,并试图锁定另一个线程。例如,考虑这个简单的例子:

public class TwoLockRunnable implements Runnable {

    private Lock lockInConstructor;
    private Lock lockInRuntime;

    public TwoLockThread(Lock lockInConstructor, Lock lockInRuntime) {
        this.lockInConstructor = lockInConstructor;
        this.lockInRuntime = lockInRuntime;

        this.lockInConstructor.lock();
    }

    @Override
    public void run() {
        lockInRuntime.lock();

        System.out.println("After the lock in run()");
    }

    public static void main(String[] args) {
        Lock lock1 = new ReentrantLock();
        Lock lock2 = new ReentrantLock();

        TwoLockRunnable runnable1 = new TwoLockThread(lock1, lock2);
        TwoLockRunnable runnable2 = new TwoLockThread(lock2, lock1);

        new Thread(runnable1).start();
        new Thread(runnable2).start();
    }
}

第一个线程在其构造函数中锁定
lock1
,第二个线程在其构造函数中锁定
lock2
。然后,第一个线程在运行时尝试锁定
lock2
,但它无法锁定,因为锁由另一个线程持有。类似地,第二个线程在运行时尝试锁定
lock1
,但由于同样的原因失败。因此,您会遇到死锁,并且在锁定运行()之后,消息将永远不会打印。

与Mureinik的类似,这是“同步”演示:

public class DeadLockAATest {

static void methodA(DeadLockAATest d1, DeadLockAATest d2) {
    synchronized (d1) {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (d2) {
            System.out.println("\t\t\tmethodA:" + Thread.currentThread().getName());
        }
    }
}

public static void main(String[] args) {
    DeadLockAATest d1 = new DeadLockAATest(), d2 = new DeadLockAATest();
    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("t1-start:" + Thread.currentThread().getName());
            methodA(d1, d2);
            System.out.println("t1-end:" + Thread.currentThread().getName());
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("t2-start:" + Thread.currentThread().getName());
            methodA(d2, d1);
            System.out.println("t2-end:" + Thread.currentThread().getName());
        }
    });
    t1.start();
    t2.start();
    System.out.println("deadlock...");
}
}

死锁输出(仅一个contion,可能t2首先启动):

你可以替换

方法a(d2,d1)

方法a(d1,d2)

这将输出:

t1-start:Thread-0
t2-start:Thread-1
deadlock...
            methodA:Thread-0
t1-end:Thread-0
            methodA:Thread-1
t2-end:Thread-1

这不是死锁,希望能帮助您。

与Mureinik的一样,这是“同步”演示:

public class DeadLockAATest {

static void methodA(DeadLockAATest d1, DeadLockAATest d2) {
    synchronized (d1) {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (d2) {
            System.out.println("\t\t\tmethodA:" + Thread.currentThread().getName());
        }
    }
}

public static void main(String[] args) {
    DeadLockAATest d1 = new DeadLockAATest(), d2 = new DeadLockAATest();
    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("t1-start:" + Thread.currentThread().getName());
            methodA(d1, d2);
            System.out.println("t1-end:" + Thread.currentThread().getName());
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("t2-start:" + Thread.currentThread().getName());
            methodA(d2, d1);
            System.out.println("t2-end:" + Thread.currentThread().getName());
        }
    });
    t1.start();
    t2.start();
    System.out.println("deadlock...");
}
}

死锁输出(仅一个contion,可能t2首先启动):

你可以替换

方法a(d2,d1)

方法a(d1,d2)

这将输出:

t1-start:Thread-0
t2-start:Thread-1
deadlock...
            methodA:Thread-0
t1-end:Thread-0
            methodA:Thread-1
t2-end:Thread-1
这不是僵局,希望能帮助你