博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java synchronized使用
阅读量:6929 次
发布时间:2019-06-27

本文共 5900 字,大约阅读时间需要 19 分钟。

hot3.png

先看测试方法:

package com.vincent;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * Vincent 创建于 2016/5/11. */public class Main {    public static void main(String[] args) {        ExecutorService threadPool = Executors.newCachedThreadPool();        final SynchronizedDemo synchronizedDemo=new SynchronizedDemo();        for (int i=0;i<5;i++){            threadPool.execute(new Runnable() {                public void run() {                    synchronizedDemo.b();                }            });        }        for (int i=0;i<3;i++){            threadPool.execute(new Runnable() {                public void run() {                    synchronizedDemo.a();                }            });        }    }}
  • 多个线程同时访问多个synchronized方法:
package com.vincent;import java.util.concurrent.TimeUnit;/** * Vincent 创建于 2016/5/11. */public class SynchronizedDemo {    private Object lock1 = new Object();    private Object lock2 = new Object();    long currentTimeMillis = System.currentTimeMillis();    public synchronized void a() {        long num = System.currentTimeMillis() - currentTimeMillis;        System.out.println("a.num=" + num);        try {            TimeUnit.SECONDS.sleep(2);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public synchronized void b() {        long num = System.currentTimeMillis() - currentTimeMillis;        System.out.println("b.num=" + num);        try {            TimeUnit.SECONDS.sleep(1);        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

输出如下:

b.num=2a.num=1003a.num=3003a.num=5004b.num=7004b.num=8004b.num=9004b.num=10004

由此可以看出:多线程在同一时刻只能有一个线程访问对象的synchronized方法

  • 多线程同时访问一个synchronized方法,一个非synchronized方法
package com.vincent;import java.util.concurrent.TimeUnit;/** * Vincent 创建于 2016/5/11. */public class SynchronizedDemo {    private Object lock1 = new Object();    private Object lock2 = new Object();    long currentTimeMillis = System.currentTimeMillis();    public synchronized void a() {        long num = System.currentTimeMillis() - currentTimeMillis;        System.out.println("a.num=" + num);        try {            TimeUnit.SECONDS.sleep(2);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public void b() {        long num = System.currentTimeMillis() - currentTimeMillis;        System.out.println("b.num=" + num);        try {            TimeUnit.SECONDS.sleep(1);        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

输出:

b.num=15b.num=16a.num=16b.num=16b.num=16b.num=16a.num=2016a.num=4016

由此看出:如果有线程访问synchronized方法,其他线程访问非synchronized方法不受影响

  • 多线程同时访问多个synchronized关键字修饰的代码块
package com.vincent;import java.util.concurrent.TimeUnit;/** * Vincent 创建于 2016/5/11. */public class SynchronizedDemo {    private Object lock1 = new Object();    private Object lock2 = new Object();    long currentTimeMillis = System.currentTimeMillis();    public void a() {        synchronized (this) {            long num = System.currentTimeMillis() - currentTimeMillis;            System.out.println("a.num=" + num);            try {                TimeUnit.SECONDS.sleep(2);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public void b() {        synchronized (this) {            long num = System.currentTimeMillis() - currentTimeMillis;            System.out.println("b.num=" + num);            try {                TimeUnit.SECONDS.sleep(1);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

输出:

b.num=1a.num=1002a.num=3002a.num=5003b.num=7003b.num=8003b.num=9003b.num=10004

由此可以看出:该用法和示例1作用相同

  • synchronized修饰的代码块使用其他同一个对象加锁
package com.vincent;import java.util.concurrent.TimeUnit;/** * Vincent 创建于 2016/5/11. */public class SynchronizedDemo {    private Object lock1 = new Object();    private Object lock2 = new Object();    long currentTimeMillis = System.currentTimeMillis();    public void a() {        synchronized (lock1) {            long num = System.currentTimeMillis() - currentTimeMillis;            System.out.println("a.num=" + num);            try {                TimeUnit.SECONDS.sleep(2);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public void b() {        synchronized (lock1) {            long num = System.currentTimeMillis() - currentTimeMillis;            System.out.println("b.num=" + num);            try {                TimeUnit.SECONDS.sleep(1);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

输出:

b.num=2a.num=1003b.num=3003b.num=4004b.num=5004b.num=6004a.num=7004a.num=9004

结果同1

  • synchronized修饰的代码块使用其他不同对象加锁
package com.vincent;import java.util.concurrent.TimeUnit;/** * Vincent 创建于 2016/5/11. */public class SynchronizedDemo {    private Object lock1 = new Object();    private Object lock2 = new Object();    long currentTimeMillis = System.currentTimeMillis();    public void a() {        synchronized (lock1) {            long num = System.currentTimeMillis() - currentTimeMillis;            System.out.println("a.num=" + num);            try {                TimeUnit.SECONDS.sleep(2);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public void b() {        synchronized (lock2) {            long num = System.currentTimeMillis() - currentTimeMillis;            System.out.println("b.num=" + num);            try {                TimeUnit.SECONDS.sleep(1);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

输出:

b.num=1a.num=2b.num=1002b.num=2002a.num=2003b.num=3003b.num=4003a.num=4003

由此看出:访问a和b的线程互不影响

转载于:https://my.oschina.net/vincentzhao/blog/673695

你可能感兴趣的文章
IoT设备程序开发及编译环境搭建初体验
查看>>
软件版本号规范与命名原则
查看>>
Spring Cloud构建微服务架构(七)消息总线
查看>>
专业的web打印插件
查看>>
xubuntu 17.04 和 iphone 6互传文件方法——使用libimobiledevice就可以像u盘一样操作文件了...
查看>>
mysql点滴_02程序中运行sql语句报字符集问题解决
查看>>
漫谈机器学习经典算法—人工神经网络
查看>>
水木清华社区招聘信息定时抓取
查看>>
七牛大数据平台的演进与大数据分析实践--转
查看>>
iOS -- SKPhysicsWorld类
查看>>
springCloud项目练习
查看>>
如何在 Azure 中均衡 Linux 虚拟机负载以创建高可用性应用程序
查看>>
php中parse_url函数解析
查看>>
易我数据恢复
查看>>
nodejs开发——require与exports的使用
查看>>
bitcoin源码解析 - 交易 Transcation (一)
查看>>
jquery easyui:EasyUI Treegrid 树形网格
查看>>
深入学习Redis(1):Redis内存模型
查看>>
xml
查看>>
unique_ptr与std::move的使用
查看>>