java线程安全篇之synchronized 多个线程多个锁(二)

来源:互联网 发布:动态恐怖漫画软件 编辑:程序博客网 时间:2024/05/17 19:17

科技快讯

      北京时间15日晚据CNBC报道,微软创始人比尔-盖茨表示,技术可能将加剧贫富差距。因为技术进步所带来的好处,可能不是每个人都能享受到。
      他在沙特利雅得举办的米斯克全球论坛(Misk Global Forum)表示,“如果我们不小心,技术会加剧富人和穷人之间的差距。因为如果技术只在费用昂贵的学校教授,它就不能惠及每一个人。”
      这位亿万富翁还谈到了人工智能(AI)的担忧,他表示,类似人工智能(AI)这样的科技进步所带来的好处超过了任何潜在的陷阱,“我们处在一个短缺的世界,而这些进步将帮助我们解决所有首要问题。”
      在几天前,著名物理学家史蒂芬-霍金-对AI的出现发出警告,称这可能是“人类文明史上最糟糕的事件”,除非社会找到控制其发展的方法。

多个线程多个锁

快速理解

      多个线程,每个线程都可以拿到自己指定的锁,分别获得锁之后,执行synchronized方法体的内容。

案例
package cn.hfbin.base.sync002;/** * @author cn.hfbin * */public class MultiThread {    private int num = -1;    /** static */    public synchronized void printNum(String tag){        try {            if(tag.equals("a")){                num = 1;                System.out.println("Thread m1");                Thread.sleep(1000);            } else {                num = 2;                System.out.println("Thread m2");            }            System.out.println("Thread " + tag + ", num = " + num);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    //注意观察run方法输出顺序    public static void main(String[] args) {        //两个不同的对象        final MultiThread m1 = new MultiThread();        final MultiThread m2 = new MultiThread();        Thread t1 = new Thread(new Runnable() {            @Override            public void run() {                m1.printNum("a");            }        });        Thread t2 = new Thread(new Runnable() {            @Override             public void run() {                m2.printNum("b");            }        });             t1.start();        t2.start();    }}

打印结果:

Thread m1Thread m2Thread b, num = 2Thread a, num = 1

按照我们正常的思维打印的结果应该是

Thread m1Thread b, num = 2Thread m2Thread a, num = 1

如此说明 关键字synchronized取得的锁都是对象锁,他们互不影响,m1和m2的信息都保存在自己的线程栈中,对其他线程不可见,t1和t2并发执行。

如果在printNum方法上加上static关键字,那它的打印结果又将会是怎样呢。如下案例:

public class MultiThread {    private static int num = -1;    /**     * static     */    public static synchronized void printNum(String tag) {        try {            if (tag.equals("a")) {                num = 1;                System.out.println("Thread m1");                Thread.sleep(1000);            } else {                num = 2;                System.out.println("Thread m2");            }            System.out.println("Thread " + tag + ", num = " + num);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    //注意观察run方法输出顺序    public static void main(String[] args) {        //俩个不同的对象        final MultiThread m1 = new MultiThread();        final MultiThread m2 = new MultiThread();        Thread t1 = new Thread(new Runnable() {            @Override            public void run() {                m1.printNum("a");            }        });        Thread t2 = new Thread(new Runnable() {            @Override            public void run() {                m2.printNum("b");            }        });        t1.start();        t2.start();    }}

打印的结果

Thread m1Thread b, num = 2Thread m2Thread a, num = 1

加上了static之后打印结果才是我们预料之中的结果,在printNum方法上加上static关键字,表示锁定class类。不管声明多少个MultiThread引用,printNum方法跟随类存放在堆上,线程间会共享资源,输出结果会等m1信息输出结束之后才会开始输出m2信息

案例总结

关键字synchronized取得的锁都是对象锁,而不是把一段代码(方法)当做锁,所以示例代码中那个线程先执行synchronized关键字的方法,那个线程就持有该方法所属对象的锁(Lock),两个对象,线程获得的就是两个不同的锁,他们互不影响。有一种情况则是相同的锁,即在静态方法上加synchronized关键字,表示锁定.class类,类一级别的锁(独占.class类)。

源代码:https://github.com/hfbin/Thread_Socket/tree/master/Thread/sync002

阅读全文
0 0
原创粉丝点击