您的位置:首页 > 其它

多线程(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也唤醒了本方,

做了不必要的判断



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: