多线程2

多线程

程序有没有存在安全隐患呢?

分析:

1,查看线程代码中是否有共享数据。

2,这个共享数据有没有被多条语句所操作。 

发现,sum是共享数据。有两条语句在操作这个共享数据,如果这两条语句被多个线程分开执行。

也就是一个线程没有执行完,其他线程就参与执行,就容易发生安全问题.

解决办法:加入同步机制。 将需要被一个线程一次执行完的代码存储带同步代码块中 。

同步代码块是用于封装代码的。

而函数也是用封装代码的。所不同之处是同步带有锁机制。

那么如果让函数这个封装体具备同步的特性。不就可以取代同步代码块了吗?

 

怎么让函数具备同步性呢?

其实很简单,只要在函数上加上一个同步关键字修饰即可。

这就是同步的另一个体现形式:同步函数。 

虽然同步的出现解决了线程安全问题。

但是也带来了一些弊端

1,效率会降低。

2,容易引发死锁。

死锁经常出现的状况为:同步嵌套

饿汉式

当多个线程并发执行getInstance方法时,容易发生线程安全问题。

因为s是共享数据,有多条语句在操作共享数据。

 

解决方式很简单。只要让getInstance方法具备同步性即可.

这虽然解决了线程安全问题,但是多个线程每一次获取该实例,都要

调用这个方法,每次调用都判断一次锁,所以效率会比较低.

 

为了保证安全,同时为了提高效率.可以通过双重判断的形式来完成。

原理:就是减少线程判断的锁次数。

 

虽然解决安全问题,也解决了效率问题,但是代码过多。

所以建议使用饿汉式体现单例设计模式。

 

验证静态同步函数到底用的是哪个锁?

 

静态同步函数使用的锁肯定不是this

因为静态函数中不可以定义this

 

静态随着类的加载而加载,这时有可能内容还没有该类对象对象。

但是一个类加载进内存,会先将这个类对应的字节码文件封装成对象。

该对象的表示方式  类名.class  代表一个类字节码文件对象,

该对象在内存中是唯一的。

静态同步函数使用的锁就是 该类对应字节码文件对象。 也就是 类名.class

 

同步函数和同步代码的区别:

同步代码块使用的锁可以是任意对象。

同步函数使用的锁是固定对象 this

 

所以一般定义同步时,建议使用 同步代码块当然,如果对象可以使用this。那么可以简化同步函数的形式。

等待/唤醒 机制

使用的方法是 :

wait():让线程等待。将线程存储到一个线程池中。

notify():唤醒被等待的线程。通常都唤醒线程池中的第一个。让被唤醒的线程处于临时阻塞状态。

notifyAll(): 唤醒所有的等待线程。将线程池中的所有线程都唤醒,让它们从冻结状体转到临时阻塞状态.

这三个方法用于操作线程,可是定义在了Object类中,为什么呢?

因为,这三个方法在使用时,都需要定义在同步中,要明确这些方法所操作的线程所属于锁。

简单说。在A锁被wait的线程,只能被A锁的notify方法唤醒。

 

所以必须要表示wait notify方法所属的锁对象,而锁对象可以是任意的对象。

可以被任意的对象调用的方法肯定定义在Object类中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值