文档章节

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
粉丝 41
博文 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.lang.ThreadLocal类研究

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

SDK4
2011/09/17
0
2
Java多线程下 ThreadLocal 的应用实例

ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程” 。其实,ThreadLocal并不是一个 Thread,而是 Thread 的局部变量,也许把它命名为 ThreadLocalVariable更容易让人理解一些。...

空云万里晴
2014/01/06
0
0
MyCat实现多租户时使用ThreadLoacl碰到的问题

使用mycat实现多租户为每个用户分表时,我想用ThreadLoacl来保存每个用户对应的数据库下面是我的Threadlocal工具类 public class ThreadLocalUtil { private static ThreadLocal tenanThrea...

石玉军
2017/10/20
196
1

没有更多内容

加载失败,请刷新页面

加载更多

spark安装测试

spark安装测试 由于本地已经安装好hadoop相关组件,所以本文是在yarn的基础上对spark进行安装及测试 确保hdfs及yarn成功启动,hadoop版本为2.7.3 安装scala,由于本人安装的spark是2.4.0,对应...

-九天-
18分钟前
2
0
周末看完了《电能计量自动化技术》

整体质量还行,下面分别将心得记录如下: 第一章:发展历程可以看看,现在算是智能电网阶段 2:讲主站系统。以文件进行各模块的交互很值得思考,尤其是批量数据,多团队合作的情况下。另外线...

max佩恩
39分钟前
7
0
mybatis批量update操作的写法,及批量update报错的问题解决方法

mybatis的批量update操作写法很简单,如下: 如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿...

编程SHA
今天
16
0
EOS怎样删除钱包

在使用Eos的keosd钱包软件时,如果要删除EOS中指定名称的钱包,最简单的办法是 直接删除钱包文件,不过在删除钱包之前,需要先停止钱包软件的运行。 学习EOS应用开发要选这个:【EOS智能合约...

汇智网教程
今天
11
0
Java语言快速实现简单MQ消息队列服务

使用 JAVA 语言自己动手来写一个MQ (类似ActiveMQ,RabbitMQ) 主要角色 首先我们必须需要搞明白 MQ (消息队列) 中的三个基本角色 ProducerBrokerConsumer 整体架构如下所示 自定义协议 首...

微笑向暖wx
今天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部