同步代码块 synchronized

  • A+
所属分类:多线程 面试

一,线程的同步

     原因: Java允许多线程并发执行,当多个线程同时操作一个可共享资源时,将会导致相互之间产生冲突,因此加入同步锁来避免该线程没有完成操作之前,被其他线程的调用,从而保证该资源的唯一性和准确性。

 三种实现同步方式:

  •     同步代码块

  •      同步方法

  •     锁机制   Lock

格式:


  1. synchronized(任意对象){


  2. 操作共享数据的代码


  3. }

注意:

默认情况锁是打开的,只要有一个线程进去执行代码,锁就会关闭

当线程执行完出来了,锁才会自动打开

锁对象可以是任意对象,但是多个线程必须使用同一把锁

好处:解决了多线程的数据安全问题

弊端:当线程很多时,因为每个线程都会去判断同步上的锁,很消耗资源,降低程序运行效率 

 什么叫代码的同步

 使用同步锁以避免在该线程没有完成操作之前,被其他线程的调用,从而保证该变量的唯一性和准确性

二,同步方法

格式:


  1. 修饰符 synchronized 返回值类型 方法名(方法参数){


  2. }

 区别:

  • 同步代码块可以锁住指定代码,同步方法是锁住方法中所有代码

  • 同步代码块可以指定锁住对象,同步方法不能

注意:

 同步方法是有默认存在的锁对象

对于非static方法,同步锁就是this

对于static方法,我们使用当前方法所在类的字节码对象

三,Lock锁 

 JDK5后提供了一个新的锁对象

提供了获得锁和释放锁的方法:

  •  void lick()  获得锁

  • void unlock() 释放锁

Lock锁是接口不能直接实例化,采用实现类ReentrantLock来实例化

Lock lock = new ReentLock();

死锁:

 两个线程对两个同步锁对象具有循环依赖,就大概会出现死锁

比如:

将大象放进冰箱!
大象锁:冰箱你把门打开,我才过去!
冰箱锁:你走过来,我才打开门!

避免:不适用锁的嵌套

生产者消费者

 比如:顾客和厨师

同步代码块 synchronized

同步代码块 synchronized 

线程池的使用:


  1. public class Demo2 {


  2. public static void main(String[] args) {


  3. //新建了一个线程任务


  4. Demo2Runnable demo2Runnable = new Demo2Runnable();


  5. ExecutorService executorService = Executors.newFixedThreadPool(5);


  6. //submit:将线程任务提交到线程池中   执行线程


  7. executorService.submit(demo2Runnable);


  8. executorService.submit(demo2Runnable);


  9. executorService.submit(demo2Runnable);


  10. executorService.submit(demo2Runnable);


  11. executorService.submit(demo2Runnable);


  12. //关闭线程池


  13. executorService.shutdown();



  14. }


  15. }

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: