多个对象多个锁问题?

本人初学多线程,在关于多个线程访问多个对象的时候会产生多个锁问题有点疑问。

代码



public class HasSelfPrivateNum {
    //num放在方法外面
    private int num = 0;

     synchronized public void addI(String username) {
        try {            
            if (username.equals("a")) {
                num = 100;
                System.out.println("a set over!");
                Thread.sleep(2000);
            } else {
                num = 200;
                System.out.println("b set over!");
            }
            System.out.println(username + "  num=" + num);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

下面是两个线程,线程A,线程B



public class ThreadA extends Thread {
    private HasSelfPrivateNum numRef;

    public ThreadA(HasSelfPrivateNum numRef) {
        this.numRef = numRef;
    }

    @Override
    public void run() {
        numRef.addI("a");
    }
}
public class ThreadB extends Thread {
    private HasSelfPrivateNum numRef;

    public ThreadB(HasSelfPrivateNum numRef) {
        this.numRef = numRef;
    }

    @Override
    public void run() {
        numRef.addI("b");
    }
}

测试类

public class Run {
    public static void main(String[] args) {
        /**
         * 两个线程分别访问同一个类的不同实例的相同名称的同步方法 本类访问同步方法数据会按顺序打印结果
         * 但实际效果确实异步形式,创建了同一个对象的两个不同实例numRef1,numRef2所以访问时两次访问了同步锁方法,所以运行结果是异步的
         */
        /**
         * synchronized取得的是对象锁,而不是把一段代码或方法当锁,
         * 所以,哪个线程先执行带synchronized关键字的方法,哪个对象就持有该方法的锁,这里就是ThreadA先持有锁
         * 那么其他线程(ThreadB)只能为等待状态。
         * 当然这里有个前提:多个线程访问的是同一个对象,那这里就有两个对象(numRef1,numRef2)所以不符合这种情况
         */
        HasSelfPrivateNum numRef1 = new HasSelfPrivateNum();
        ThreadA athread = new ThreadA(numRef1);
        athread.start();

        HasSelfPrivateNum numRef2 = new HasSelfPrivateNum();
        ThreadB bthread = new ThreadB(numRef2);
        bthread.start();
    }
}

图片描述

按道理addI方法是加上了同步锁的,那访问这个方法的对象都是同步的。运行结果应该是同步的
a set over
a num=100
b set over
b num=200
那为什么这里实际运行结果还是异步的呢?望解答。

阅读 3.4k
1 个回答

因为你两个线程操作的是两个对象。。。所以不存在同步的问题。
你需要让两个线程操作同一个的对象,并且加锁,这样才能实现你要的同步效果。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题