多线程(2)锁
2015-07-03 18:35
141 查看
分析多线程是否存在安全隐患:
1,线程任务中是否有共享的数据
2,是否多条操作共享数据的代码
同步函数,其实就是在函数上加上同步关键字进行修饰
同步表现形式有两种:1,同步代码块 2,同步函数
public synchronized() void aad(int n)
{
}
同步函数使用的锁是什么呢?
函数需要被对象调用,哪个对象不确定,但是都用this来表示
同步函数使用的锁就是this
***验证同步函数使用的锁是this。
验证需求:
启动两个线程
一个线程负责执行同步代码块 (使用明锁)
另一个线程使用同步函数(使用this锁)。
两个执行的任务是一样的都是卖票,如果他们没有使用相同的锁,说明他们没有同步,会出现数据错误
怎么能让一个线程一直在同步代码块中,一个线程在同步函数呢?
可以通过切换的方式:
boolean flag=true;
Thread t1=new Thread(t);
Thread t2=new Thread(t);
t1.start();
Thread.sleep(10);
t.flag=false;
t2.start();
**如果同步函数被static修饰呢?
static方法随着类加载,这时不一定有该类的对象,但是一定有一个该类的字节码文件对象
这个对象简单的表示方式就是 类名.class 描述类的是 Class
单例模式的并发访问:
**饿汉式:相对与多线程并发,安全
***懒汉式,延迟加载模式
在多线程并发访问时,会出现线程安全问题
加了同步就可以解决问题,无论是同步函数,还是同步代码块都行
但是效率低了,
怎么解决效率低的问题。
可以通过if对单例对象的双重判断形式
if(s==null)
{
synchronized(Single.class)
{
if(s==null)
s=new Single();
}
}
**同步函数,同步代码块 区别
同步代码块使用的是任意的对象作为锁。
同步函数只能使用this作为锁
如果说:一个类中只需要一个锁,这时可以考虑同步函数,使用this,写法简单
但是,一个类中需要多个锁,还有多个类中使用同一个锁,这时只能使用同步代码块。
建议使用同步代码块。
死锁:
1, 同步嵌套
**多线程间的通信: 多个线程都在处理同一个资源,但是处理的任务却不一样
生产者,消费者、
通过同步,解决了没生产就消费的问题、
但是出现了连续的生产没有消费的情况,和需求生产一个,消费一个的情况不符。
使用了等待唤醒机制。
wait():该方法可以让线程处于冻结状态,并将线程临时存储到线程池中。
notify(); 唤醒指定线程池中的任意一个线程
notifyAll();唤醒指定线程池中的所有线程。
这些方法必须使用在同步中,因为它们用来操作同步锁上的线程的状态的。
在使用这些方法时,必须标识它们所属于的锁。标识方式就是 锁对象.wait();锁对象.notify();锁对象.notifyAll();
相同锁的notify(),可以获取相同锁的wait();
***多生产多消费。
问题1:重复生产,重复消费。
原因:经过复杂的(等,资格)分析,发现被唤醒的线程没有判断标识就开始工作(生产or消费)了
导致了重复的生产和消费的发生
解决:那就是被唤醒的线程必须判断标识
使用while循环搞定
问题2:
死锁了。所有的线程都处于冻结状态。
原因:本方线程在唤醒时,又一次唤醒了本方线程,而本方线程循环判断标识,又继续等待,
导致所有线程都等待了
解决:希望本方如果唤醒了对方线程,就可以解决。
可以使用notifyAll()方法。
那不是全唤醒了吗? 是的,既有本方,又有对方,但是本方醒后,会判断标识继续等待。
这样对方就有线程可以执行了
已经实现了多生产多消费。
但是有些小问题,效率有点低,因为notifyAll也唤醒了本方,
做了不必要的判断
分析多线程是否存在安全隐患:
1,线程任务中是否有共享的数据
2,是否多条操作共享数据的代码
同步函数,其实就是在函数上加上同步关键字进行修饰
同步表现形式有两种:1,同步代码块 2,同步函数
public synchronized() void aad(int n)
{
}
同步函数使用的锁是什么呢?
函数需要被对象调用,哪个对象不确定,但是都用this来表示
同步函数使用的锁就是this
***验证同步函数使用的锁是this。
验证需求:
启动两个线程
一个线程负责执行同步代码块 (使用明锁)
另一个线程使用同步函数(使用this锁)。
两个执行的任务是一样的都是卖票,如果他们没有使用相同的锁,说明他们没有同步,会出现数据错误
怎么能让一个线程一直在同步代码块中,一个线程在同步函数呢?
可以通过切换的方式:
boolean flag=true;
Thread t1=new Thread(t);
Thread t2=new Thread(t);
t1.start();
Thread.sleep(10);
t.flag=false;
t2.start();
**如果同步函数被static修饰呢?
static方法随着类加载,这时不一定有该类的对象,但是一定有一个该类的字节码文件对象
这个对象简单的表示方式就是 类名.class 描述类的是 Class
单例模式的并发访问:
**饿汉式:相对与多线程并发,安全
***懒汉式,延迟加载模式
在多线程并发访问时,会出现线程安全问题
加了同步就可以解决问题,无论是同步函数,还是同步代码块都行
但是效率低了,
怎么解决效率低的问题。
可以通过if对单例对象的双重判断形式
if(s==null)
{
synchronized(Single.class)
{
if(s==null)
s=new Single();
}
}
**同步函数,同步代码块 区别
同步代码块使用的是任意的对象作为锁。
同步函数只能使用this作为锁
如果说:一个类中只需要一个锁,这时可以考虑同步函数,使用this,写法简单
但是,一个类中需要多个锁,还有多个类中使用同一个锁,这时只能使用同步代码块。
建议使用同步代码块。
死锁:
1, 同步嵌套
**多线程间的通信: 多个线程都在处理同一个资源,但是处理的任务却不一样
生产者,消费者、
通过同步,解决了没生产就消费的问题、
但是出现了连续的生产没有消费的情况,和需求生产一个,消费一个的情况不符。
使用了等待唤醒机制。
wait():该方法可以让线程处于冻结状态,并将线程临时存储到线程池中。
notify(); 唤醒指定线程池中的任意一个线程
notifyAll();唤醒指定线程池中的所有线程。
这些方法必须使用在同步中,因为它们用来操作同步锁上的线程的状态的。
在使用这些方法时,必须标识它们所属于的锁。标识方式就是 锁对象.wait();锁对象.notify();锁对象.notifyAll();
相同锁的notify(),可以获取相同锁的wait();
***多生产多消费。
问题1:重复生产,重复消费。
原因:经过复杂的(等,资格)分析,发现被唤醒的线程没有判断标识就开始工作(生产or消费)了
导致了重复的生产和消费的发生
解决:那就是被唤醒的线程必须判断标识
使用while循环搞定
问题2:
死锁了。所有的线程都处于冻结状态。
原因:本方线程在唤醒时,又一次唤醒了本方线程,而本方线程循环判断标识,又继续等待,
导致所有线程都等待了
解决:希望本方如果唤醒了对方线程,就可以解决。
可以使用notifyAll()方法。
那不是全唤醒了吗? 是的,既有本方,又有对方,但是本方醒后,会判断标识继续等待。
这样对方就有线程可以执行了
已经实现了多生产多消费。
但是有些小问题,效率有点低,因为notifyAll也唤醒了本方,
做了不必要的判断
相关文章推荐
- 面向服务的大数据分析平台解决方案
- LeetCode(110) Balanced Binary Tree
- device mapper的使用
- Animation动画详解(三)—— 代码生成alpha、scale、translate、rotate、set及插值器动画
- DLL
- 使用apk1.5.3反编译的问题
- 网上资源
- unity里利用C# 读写XML
- Linux-2.6.32 NUMA架构之内存和调度
- HTTP_3_HTTP报文
- 大数据平台解决方案
- NUMA与英特尔下一代Xeon处理器学习心得
- 三个你在书中无法学到的数据分析知识
- [转] iOS开发之使用lipo命令制作模拟器与真机通用静态库
- LeetCode-Excel Sheet Column Number-解题报告
- 第十七周oj刷题——Problem E: C++习题 输入输出--私有继承
- 解决Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future:
- 诸葛:为数据分析瘦身法
- ios说说自己的计划是什么样的发展论坛
- Eclipse开发工具与SVN完美结合使用