博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
软件架构阅读笔记07
阅读量:5058 次
发布时间:2019-06-12

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

关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。本文探讨synchronized关键字。

synchronized关键字可以修饰方法,可以修饰代码块,但不能修饰构造器、属性等。

synchronized(this)的一些理解

当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的除synchronized(this)同步代码块以外的部分。

第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

以上规则对其它对象锁同样适用。

一:synchronized同步代码块

public class SyncThread1 implements Runnable {

    private Integer key = 0;

    @Override

    public void run() {

        // key是Integer对象(注意不是int,因为int不是对象)

        // 线程进入下面同步代码之前,需要先获取key的锁。

        // 需要结果是key实现自增长,如果没有同步块,则可能会出现重复key值的现象

        synchronized (key) {

            key++;

            System.out.println(Thread.currentThread().getName() + ":" + key);

            try {

                Thread.sleep(100);

            } catch (InterruptedException e) {

            }

        }

    }

    public static void main(String[] args) {

        SyncThread1 st = new SyncThread1();

        

        for(int i=0; i<10; i++) {

            new Thread(st, "Thread" + i).start();

        }

    }

输出:

Thread1:2

Thread3:3

Thread5:4

Thread7:5

Thread0:2

Thread2:7

Thread9:6

Thread4:8

Thread6:9

Thread8:10

二:synchronized同步方法

同步方法分静态和非静态两种。静态方法则一定会同步,非静态方法需在单例模式才生效,推荐用静态方法(不用担心是否单例)。

2.1 非静态方法同步示范

// 如果是同步方法,则分静态和非静态两种。

// 静态方法则一定会同步,非静态方法需在单例模式才生效,推荐用静态方法(不用担心是否单例)。

public class SyncThread2 implements Runnable {

    private Integer key = 0;

 

    // 此示范为非静态方法同步

    public synchronized Integer getKey() {

        key++;

        return key;

    }

    @Override

    public void run() {

        System.out.println(Thread.currentThread().getName() + ":" + getKey());

        try {

            Thread.sleep(10);

        } catch (InterruptedException e) {

        }

    }

    public static void main(String[] args) {

        // 非静态方法同步,需要启动单例模式

        SyncThread2 st = new SyncThread2();

        for (int i = 0; i < 10; i++) {

            new Thread(st, "Thread" + i).start();

        }

    }

}

输出:

Thread0:1

Thread1:3

Thread2:2

Thread3:5

Thread5:6

Thread7:7

Thread9:8

Thread6:9

Thread8:10

Thread4:4

 

2.2 静态方法同步示范

// 如果是同步方法,则分静态和非静态两种。

// 静态方法则一定会同步,非静态方法需在单例模式才生效,推荐用静态方法(不用担心是否单例)。

public class SyncThread3 implements Runnable {

    private static Integer key = 0;

    // 此示范为静态方法同步

    public synchronized static Integer getKey() {

        key++;

        return key;

    }

    @Override

    public void run() {

        System.out.println(Thread.currentThread().getName() + ":" + getKey());

        try {

            Thread.sleep(10);

        } catch (InterruptedException e) {

        }

    }

    public static void main(String[] args) {

        // 如果用静态方法实现同步,则可以生成对象的多个实例

        for (int i = 0; i < 10; i++) {

            SyncThread3 st = new SyncThread3();

            new Thread(st, "Thread" + i).start();

        }

    }

输出:

Thread3:3

Thread1:1

Thread0:2

Thread5:4

Thread7:5

Thread9:6

Thread2:7

Thread8:10

Thread6:9

Thread4:8

总结

1、无论是同步代码块还是同步方法,必须获得对象锁才能够进入同步代码块或者同步方法进行操作。

2、如果采用方法级别的同步,对象锁为方法所在的对象;如果是静态同步方法,对象锁为方法所在的类(唯一)。

3、对于代码块,对象锁即指synchronized(object)中的object。

转载于:https://www.cnblogs.com/y862621115/p/11059193.html

你可能感兴趣的文章
一个自己写的判断2个相同对象的属性值差异的工具类
查看>>
oracle连接的三个配置文件(转)
查看>>
pytho logging
查看>>
Python内置函数(29)——help
查看>>
oracle导出/导入 expdp/impdp
查看>>
JAVA 技术类分享(二)
查看>>
Objective - C基础: 第四天 - 10.SEL类型的基本认识
查看>>
Android TextView加上阴影效果
查看>>
OA项目设计的能力③
查看>>
《梦断代码》读书笔记(三)
查看>>
Java8 Lambda表达应用 -- 单线程游戏server+异步数据库操作
查看>>
[Unity3D]Unity3D游戏开发MatchTarget的作用攀登效果实现
查看>>
AngularJS学习篇(一)
查看>>
关于Xshell无法连接centos6.4的问题
查看>>
css3动画——基本准则
查看>>
输入月份和日期,得出是今年第几天
查看>>
pig自定义UDF
查看>>
Kubernetes 运维学习笔记
查看>>
spring security 11种过滤器介绍
查看>>
代码实现导航栏分割线
查看>>