2.1 线程同步的基本概念

出现的问题:
多个线程操作同一个资源对象——>并发问题2、线程的同步机制 - 图1

如何解决:
加入线程同步机制(Synchronized)
线程同步的基本概念(线程等待机制)
处理多线程问题,即多个线程操作同一资源对象,并且某些线程还要修改这个资源对象,那么就需要加入线程同步机制:线程同步本质上是一种等待机制,
多个需要同时访问此对象的线程进入这个对象的等待迟形成线程队列,每个线程只有等前面的线程使用完毕,下一个线程才可以使用。

2.2 线程同步的创建

线程形成的条件: 队列+ 锁机制
由于多个线程操作同个资源对象时,导致访问数据冲突,会产生线程安全问题。 为了保证数据再方法中被访问的正确性,在多线程访问时加入了锁机制(synchronized):当一个线程访问资源对象时,即会获得对象的排它锁,独占资源,此时其他线程必须等待,只有等使用后释放锁之后,其他线程才可以继续访问资源对象。
加入线程同步机制后出现的缺点:保证了资源对象的安全性,但相应降底了程序运行的性能。
Synchronized关键字:
(1)Synchronized修饰方法:**public synchroniezd void method(args……)**

synchronized方法控制“对象”的访问,每个对象对应一把锁,每个用synchronized方法都必须调用该方法的对象锁才能执行,否则线程会阻塞,一旦获得对象锁,方法一旦执行,直到该方法返回才释放锁,后面被阻塞等待的线程才能获得这个锁,继续调用。
(2) synchronized修饰方法的弊端
2、线程的同步机制 - 图2
(3)Synchronized方法块 : **synchronized (obj){ }
obj称之为
同步监视器,同步监视器可以是任意对象,但一般推荐使用被操作的共享资源作为同步监视器
同步方法中无需指定同步监视器,因为方法中的this即为同步监视器。
(4)同步监视器的执行过程:**
第一个线程访问方法,锁定了同步监视器,执行线程执行体方法
第二线程访问方法,发现同步监视器被锁定,无法执行程序,进入阻塞等待状态
第一个线程访问完毕,释放同步监视器
此时第二个线程访问方法,此时锁定了同步监视器。开始执行程序。

2.3 死锁

死锁即多个线程操作统一资源对象时,互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形。某一个同步块同时拥有“两个以上对象的锁”时,就可能会发生“死锁”的问题。
死锁产生的四个必要条件:
1、互斥条件:一个资源每次只能被一个进程使用。
2、请求与保持条件:一个进程因请求资源被阻塞,对已有的资源保持不放。
3、不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
4、循环等待条件:若干进程之间形成一种头尾相接的循环等待关系。

2.4 lock锁

2、线程的同步机制 - 图3
2、线程的同步机制 - 图4
lock锁和synchronized锁的区别?
(1)Lock不是Java语言内置的,synchronized是Java语言的关键字,因此sunchronized是内置特性。Lock是一个类,通过这个类可以实现同步访问;
(2)Lock和synchronized有一点非常大的不同,采用synchronized不需要用户去手动释放锁,当synchronized方法或者synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。所以将释放锁的操作unlock()方法放在finally块中进行,以保证锁一定被被释放防止死锁的发生。