JavaSE——线程同步

为什么需要线程同步?  

  同步就是协同步调,按预定的先后次序进行运行。如:你说完,我再说而并非一起动作。“同”字应是指协同、协助、互相配合。
如进程、线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作。
 
  所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其它线程也不能调用这个方法。按照这个定义,其实绝大多数函数都是同步调用(例如sin, isdigit等)。但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。例如Window API函数SendMessage。该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回。当对方处理完毕以后,该函数才把消息处理函数所返回的LRESULT值返回给调用者。
  
  在一般情况下,创建一个线程是不能提高程序的执行效率的,所以要创建多个线程。但是多个线程同时运行的时候可能调用线程函数,在多个线程同时对同一个内存地址进行写入,由于CPU时间调度上的问题,写入数据会被多次的覆盖,所以就要使线程同步。
线程同步:即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作, 其他线程才能对该内存地址进行操作,而其他线程又处于等待状态,目前实现线程同步的方法有很多,临界区对象就是其中一种。
 
  在多线程编程里面,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多有一个线程访问,以保证数据的完整性。
    
  比如同一个银行账户被两个人消费,这两个人不能同时去用这个银行卡去付款,因为银行卡的余额有限,必须确认一次消费完成后确认此银行卡的余额还可以足够支付下一笔消费。账户内的余额相当于cpu资源,而两笔消费相当于两个线程,此时两个线程是不能同时去使用cpu资源的。
 
线程同步的操作方法:
  synchronized程序块
  synchronized方法
synchronized方法:
  public synchronized run(){
 
}    
  即在线程对象的 run()方法前加上关键字synchronized,表示该方法是原子性的,不允许两个线程并发执行,当一个线程的实例对象去执行该方法时,会对当前线程对象加一个同步锁,等它执行完任务后,在把这把锁交给另一个需要访问这个资源的线程。
 
 

 

 两个线程同时使用cpu资源,会造成一些麻烦,此时应给t1线程一把锁,给runnable 对象加上同步锁,不要允许t2线程此时运行直到t1线程完成其工作。

此处yield()方法执行了但没有起作用。

synchronized程序块:

 

 持有锁的线程以下情况会释放锁:

   执行完同步代码块;

   执行同步代码块的过程中发生异常导致线程终止;

   执行了锁所属对象的wait()方法。

注意:yield()方法和sleep()方法都不会释放锁。

如有不对之处望指正,谢谢

 
 
 
       
 
 
 
 
 
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/linlin0/p/6159760.html