多线程顺序执行任务_wait阻塞,返回锁

2018-09-14  本文已影响0人  Shokka

题目是两个线程按顺序执行任务:打印 0 - 99
起初的代码,导致两个线程都阻塞了,原因:
(只把重点放在wait会返还锁,但是忘记会阻塞线程)

package com.bnuz;


class ThreadTest extends Thread{
    public Object pre;
    public Object self;
    public int num;
    public String name;
    public ThreadTest(Object pre,Object self,int num,String name){
        this.pre = pre;
        this.self = self;
        this.num = num;
        this.name = name;
    }

    @Override
    public void run(){
        for (int i = 0 ; i < 50 ; i++){
            synchronized (pre){
                System.out.println("wake up");
                synchronized (self){
                    System.out.println(name+":"+num++);
                    try {
                        //错误 ,因为wait虽然会返回self对象的锁,但是代码阻塞在这一步,导致另一个线程也阻塞后无法唤醒当前线程,死锁。
                        self.wait();
                        System.out.println("gone");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                pre.notify();
            }
        }

    }
}
public class Main {

    public static void main(String[] args) {
        Object a = new Object();
        Object b = new Object();
        int num = 0;
        ThreadTest testa = new ThreadTest(b,a,num,"a");
        ThreadTest testb = new ThreadTest(a,b,num,"b");
        testa.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        testb.start();
    }
}

修改后的代码:

package com.bnuz;


class ThreadTest extends Thread{
    public Object pre;
    public Object self;
    public int num;
    public String name;
    public ThreadTest(Object pre,Object self,int num,String name){
        this.pre = pre;
        this.self = self;
        this.num = num;
        this.name = name;
    }

    @Override
    public void run(){
        for (int i = 0 ; i < 50 ; i++){
            synchronized (pre){
                System.out.println("wake up");
                synchronized (self){
                    System.out.println(name+":"+num++);

                        //错误 ,因为wait虽然会返回self对象的锁,但是代码阻塞在这一步,导致另一个线程也阻塞后无法唤醒当前线程,死锁。
//                        self.wait();
                        System.out.println("gone");
                        self.notify();

                }
                try {
                    pre.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
public class Main {

    public static void main(String[] args) {
        Object a = new Object();
        Object b = new Object();
        int num = 0;
        ThreadTest testa = new ThreadTest(b,a,num,"a");
        ThreadTest testb = new ThreadTest(a,b,num,"b");
        testa.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        testb.start();
    }
}

出现问题,数据同步问题,原因是基本变量的使用错误,应该使用引用变量。

上一篇下一篇

猜你喜欢

热点阅读