文档章节

Java synchronized使用

清尘V
 清尘V
发布于 2016/05/11 22:39
字数 659
阅读 55
收藏 2

先看测试方法:

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=2
a.num=1003
a.num=3003
a.num=5004
b.num=7004
b.num=8004
b.num=9004
b.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=15
b.num=16
a.num=16
b.num=16
b.num=16
b.num=16
a.num=2016
a.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=1
a.num=1002
a.num=3002
a.num=5003
b.num=7003
b.num=8003
b.num=9003
b.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=2
a.num=1003
b.num=3003
b.num=4004
b.num=5004
b.num=6004
a.num=7004
a.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=1
a.num=2
b.num=1002
b.num=2002
a.num=2003
b.num=3003
b.num=4003
a.num=4003

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

© 著作权归作者所有

共有 人打赏支持
清尘V
粉丝 43
博文 107
码字总数 47780
作品 0
青岛
程序员
synchronized与ThreadLocal

synchronized是实现java的同步机制。同步机制是为了实现同步多线程对相同资源的并发访问控制。保证多线程之间的通信。 同步的主要目的是保证多线程间的数据共享。同步会带来巨大的性能开销,...

bigYuan
2013/07/18
0
2
Java多线程学习(二)synchronized关键字(2)

系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Ja...

一只蜗牛呀
04/16
0
0
Java多线程系列之synchronized关键字解析

一、synchronized关键字介绍 synchronized关键字是JVM在软件层面实现的一种独占锁,他依赖于java对象,通过使用它可以把任意一个非空java对象作为锁,如果使用synchronized关键字修饰类中的实...

老韭菜
08/01
0
0
java.lang.ThreadLocal类研究

java.lang.ThreadLocal类研究 1、概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是thread local variable(线程局部变量)。也许把它命名为...

SDK4
2011/09/17
0
2
12、Java并发性和多线程-Java同步块

以下内容转自http://ifeve.com/synchronized-blocks/: Java 同步块(synchronized block)用来标记方法或者代码块是同步的。Java同步块用来避免竞争。本文介绍以下内容: Java同步关键字(s...

easonjim
2017/06/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

[雪峰磁针石博客]软件测试专家工具包1web测试

web测试 本章主要涉及功能测试、自动化测试(参考: 软件自动化测试初学者忠告) 、接口测试(参考:10分钟学会API测试)、跨浏览器测试、可访问性测试和可用性测试的测试工具列表。 安全测试工具...

python测试开发人工智能安全
今天
2
0
JS:异步 - 面试惨案

为什么会写这篇文章,很明显不符合我的性格的东西,原因是前段时间参与了一个面试,对于很多程序员来说,面试时候多么的鸦雀无声,事后心里就有多么的千军万马。去掉最开始毕业干了一年的Jav...

xmqywx
今天
2
0
Win10 64位系统,PHP 扩展 curl插件

执行:1. 拷贝php安装目录下,libeay32.dll、ssleay32.dll 、 libssh2.dll 到 C:\windows\system32 目录。2. 拷贝php/ext目录下, php_curl.dll 到 C:\windows\system32 目录; 3. p...

放飞E梦想O
今天
0
0
谈谈神秘的ES6——(五)解构赋值【对象篇】

上一节课我们了解了有关数组的解构赋值相关内容,这节课,我们接着,来讲讲对象的解构赋值。 解构不仅可以用于数组,还可以用于对象。 let { foo, bar } = { foo: "aaa", bar: "bbb" };fo...

JandenMa
今天
1
0
OSChina 周一乱弹 —— 有人要给本汪介绍妹子啦

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享水木年华的单曲《中学时代》@小小编辑 手机党少年们想听歌,请使劲儿戳(这里) @须臾时光:夏天还在做最后的挣扎,但是晚上...

小小编辑
今天
68
8

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部