文档章节

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
粉丝 42
博文 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

没有更多内容

加载失败,请刷新页面

加载更多

String ,  StringBuffer ,  StringBuilder的区别

String , StringBuffer , StringBuilder的区别 String 首先,String 是用来表示一个字符串常量的,它是一个不可变对象,意味着,一旦我们创建了某个字符串之后,就不能再改变它的值了,我们可...

tsmyk0715
48分钟前
2
0
区块链100讲:UTXO 和 Account 模型对比

在当前区块链世界中,主要有两种记录保存方式,UTXO 模式(Unspent Transaction Output) 和 Account 模式。Bitcoin 采用的是 UTXO 模型,Ethereum 采用的 Account 模型,同样 CITA 也采用了 ...

HiBlock
50分钟前
1
0
Vue中路由管理器Vue Router使用介绍(三)

一、路由定义添加动态参数定义 1.路由定义项,使用:xx 方式 定义动态参数 { path:'/user/:id/:name', name:'user', component:()=>import('./views/User.vue') ...

tianma3798
51分钟前
1
0
从ibdata文件恢复mysql数据

DROP TABLE 恢复【一】 Recover InnoDB dictionary Percona Data Recovery Tool 单表恢复

IT--小哥
54分钟前
1
0
常见设计模式UML图

常见设计模式UML图 本文主要总结常见的设计模式的UML图,方便查阅和思考。 创建型模式 简单工厂模式、工厂方法模式、抽象工厂模式、建造者模式和单例模式,这五种设计模式主要处理对象的创建...

陶小陶
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部