线程的同步

一、同步方法

  使用synchronzed修饰的方法控制对类成员变量的访问

  Synchronized就是为当前的线程声明一个锁

  一次只允许有一个线程进入执行

  语法:

    访问修饰符 synchronized 返回类型 方法名 (参数列表){ ... ... }

    Synchronized 访问修饰符 返回类型 方法名 (参数列表){ ... ... }

二、同步代码块

  使用synchronized关键字修饰的代码块

  语法:

  Synchronized(syncObject){

  //需要同步的代码块

解析:

  1)yncObject为需同步的对象,通常为this

  2)效果与同步方法相同

  3)避免数据不安全问题

  4)一次只允许有一个线程进入

 

互斥与同步:守恒的能量

  1、线程的特点,共享同一进程的资源,同一时刻只能有一个线程占用CPU

  2、由于线程有如上的特点,所以就会存在多个线程争抢资源的现象,就会存在争用条件这种现象

  3、为了让线程能够正确的运行,不破坏共享的数据,所以,就产生了同步和互斥的两种线程运行的机制

  4、线程的互斥(加锁实现):线程的运行隔离开来,互不影响,使用synchronized关键字实现互斥行为,此关键字即可以出现

  在方法体之上也可以出现在方法体内,以一种块的形式出现,在此代码块中有线程的等待和唤醒动作,用于支持线程的同步控制

  5、线程的同步(线程的等待和唤醒:wait()+notifyAll()):线程的运行有相互的通信控制,运行完一个再正确的运行另一个

  6、锁的概念:比如private final Object lockObj=new Object();

  7、互斥实现方式:synchronized关键字

  synchronized(lockObj){---执行代码----}加锁操作

  lockObj.wait();线程进入等待状态,以避免线程持续申请锁,而不去竞争cpu资源

  lockObj.notifyAll();唤醒所有lockObj对象上等待的线程

  8、加锁操作会开销系统资源,降低效率

**同步和锁定

  Java中每个对象都有一个内置锁

  当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。获得一个对

  象的锁也称为获取锁、锁定对象、在对象上锁定或在对象上同步。

  当程序运行到synchronized同步方法或代码块时才该对象锁才起作用。

  一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁,直到第一个线程释放(或返回)锁。这也意

  味着任何其他线程都不能进入该对象上的synchronized方法或代码块,直到该锁被释放。

  释放锁是指持锁线程退出了synchronized同步方法或代码块。

锁和同步的要求. 

  1)、只能同步方法,而不能同步变量和类;

 

  2)、每个对象只有一个锁;当提到同步时,应该清楚在什么上同步?也就是说,在哪个对象上同步?

 

  3)、不必同步类中所有的方法,类可以同时拥有同步和非同步方法。

 

  4)、如果两个线程要执行一个类中的synchronized方法,并且两个线程使用相同的实例来调用方法,那么一次只能有一个线程能

  够执行方法,另一个需要等待,直到锁被释放。也就是说:如果一个线程在对象上获得一个锁,就没有任何其  他线程可以进入

  (该对象的)类中的任何一个同步方法。

 

  5)、如果线程拥有同步和非同步方法,则非同步方法可以被多个线程自由访问而不受锁的限制。

 

  6)、线程睡眠时,它所持的任何锁都不会释放。

 

  7)、线程可以获得多个锁。比如,在一个对象的同步方法里面调用另外一个对象的同步方法,则获取了两个对象的同步锁。

 

  8)、同步损害并发性,应该尽可能缩小同步范围。同步不但可以同步整个方法,还可以同步方法中一部分代码块。

 

  9)、在使用同步代码块时候,应该指定在哪个对象上同步,也就是说要获取哪个对象的锁。

 

多个并发线程访问同一个资源的同步代码块时、

  1. 同一时刻只能有一个线程进入synchronized (this )同步代码块
  2. 当一个线程访问一个synchronized (this) 同步代码块时,其他synchronized (this) 同步代码块同样被锁定
  3. 当一个线程访问一个synchronized (this) 同步代码块时,其他线程可以访问该资源的非synchronized (this) 同步代

小结

  1、线程同步的目的是为了保护多个线程访问一个资源时对资源的破坏。

  2、线程同步方法是通过锁来实现,每个对象都有切仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问

  该对象的线程就无法再访问该对象的其他同步方法。

  3、对于静态同步方法,锁是针对这个类的,锁对象是该类的Class对象。静态和非静态方法的锁互不干预。一个线程获得锁,当在一

  个同步方法中访问另外对象上的同步方法时,会获取这两个对象锁。

  4、对于同步,要时刻清醒在哪个对象上同步,这是关键。

  5、编写线程安全的类,需要时刻注意对多个线程竞争访问资源的逻辑和安全做出正确的判断,对“原子”操作做出分析,并保证原子操

  作期间别的线程无法访问竞争资源。

  6、当多个线程等待一个对象锁时,没有获取到锁的线程将发生阻塞。

  7、死锁是线程间相互等待锁锁造成的,在实际中发生的概率非常的小。真让你写个死锁程序,不一定好使,呵呵。但是,一旦程序发

  生死锁,程序将死掉。

 

posted @ 2018-10-09 08:49  米佳5714  阅读(94)  评论(0编辑  收藏  举报