您的位置:首页 > 编程语言 > Java开发

<JAVA学习笔记5>——线程同步、安全

2016-06-24 17:48 309 查看
1、多进程共享:

多进程共享:在多线程操作中, 多个线程有可能同时处理同一个资源, 这就是多线程中的共享数据。

比如:“厕所”;在同一时间内,只能有一个人使用。即多个人共享一个资源。

但若想保证在这段时间内只能有一个人使用“厕所”,必须在安个门。也就是说,在多进程共享的过程中,可能出现数据的不确定性,带来线程的不安全。

2、线程同步

线程同步:解决数据共享问题,必须使用同步,所谓同步就是指多个线程在同一个时间段内只能有一个线程执行指定的代码,其他线程要等待此线程完成之后才可以继续执行。

3、线程同步的方法:

(1)、同步代码块:

将要同步的代码包裹在方法中,并传入相应的同步对象锁,对象锁随便。

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

synchronized (对象锁){
需要被锁的代码.......
//线程只有拿到了锁对象,才能执行这里的代码!!!
//换言之,这里的代码如果执行了,说明该线程拿到了锁对象,其他线程不能拿到该锁对象,
//在这块代码执行完之后,对象锁就解锁了。多个线程必须使用同一个锁对象,要不然锁无效。
}


(2)、同步方法:

同步方法锁的同步对象是当前的对象。也就是说,当一个类中有两个同步方法。当一个线程在访问某一个同步方法时,即获得了当前的对象锁,其它的线程不能再访问其他的同步方法。

注:synchronized修饰静态方法,如果调用该静态方法,将锁住整个类。

public  Synchronized void method{
同步方法......
}


(3)、同步代码块、同步方法的异同:

都用Synchronized修饰

同步方法默认用this或者当前类class对象作为锁。

同步代码块可以选择以什么来加锁,比同步方法要更颗粒化,我们可以选择只同步会发生问题的部分代码而不是整个方法。

同步是高开销的操作,因此尽量减少同步的内容。通常没有必要同步整个方法,同步部分代码块即可。

由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用给方法前,要获取内置锁,否则处于阻塞状态。

(4)、Lock

Lock锁是在JDK1.5之后才出的新特性,——并发包(Lock),好处是在想加锁的地方加上,想解锁的地方解锁。对比上述的两种方法, 必须在完成相应的代码块或者相应的方法才能去掉锁,这样不免会丢失一定的性能。

// Lock锁,互斥锁
private final ReentrantLock lock = new ReentrantLock();
public void eat(){
// 上锁
lock.lock();

要锁的代码块.....

// 解锁
lock.unlock();
}


(5)、一些基本的规则:

当编写synchronized 块时, 有几个简单的准则可以遵循, 这些准则在避免死锁和性能危险的风险方面大有帮助。

(1) 使代码块保持简洁。把不随线程变化的预处理和后处理移出synchronized 块。

(2) 不要阻塞。如InputStream.read().

(3) 在持有锁的情况下, 不要调用其他对象的同步方法。

这节就到这里,期待和大家的交流。

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