并发:同一个对象,多个线程 同时操作;
例子:1.银行同一个账户,两个人同时进行存钱和取钱,造成显示余额不正确。2. 12306抢票,两人抢到同一张票
以上例子都称为线程不安全。
解决线程不安全:锁
如:一吧钥匙,两个线程(对象)都去竞争,当一个线程得到该锁,则该线程可以对这个房间进行操作,另一个线程等待,等待
第一个线程使用锁结束。
线程同步形成的两个条件:1.形成队列,等待次队列.2.加上 锁(syncharonized)机制
线程同步:由于同一进程的多个线程共享同一块存储,在带来方便的同时,也带来了访问冲突的问题,为了保证数据在方法中被访问的正确性,在访问时加入锁机制 ,
当一个线程获得对象的排它锁,独占资源,其他线程必须等待,使用后释放锁即可。 但存在以下问题:
1.一个线程持有锁会导致其他所有需要此锁的线程挂起;
2.在多线程竞争下,加锁、释放锁会导致比较多的上下文呢切换和调度延时,引起性能问题;
3.如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级导致,引起性能问题;
线程同步:
由于我们可以通过 private 关键字来保证数据对象只能被方法访问,所以我只需要针对方法提出一套机制,这套机制就是 synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。
同步方法:public synchronized void method(int args) {}
synchronized 方法控制对“成员变量 | 类变量” 对象的访问:每个对象都对应一把锁,每个 synchronized 方法都必须获得调用该方法的对象的锁才能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才能将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。
缺陷:若将一个大的方法声明为synchronized 将会大大影响效率;(因为一个方法被声明了synchronized,那么此方法独占锁,其他方法需要等待这个方法执行完毕,第二个拿到cpu调度的方法才能拿到锁,进行操作)