同步代码块 synchronized

一,线程的同步

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

 三种实现同步方式:

  •     同步代码块
  •      同步方法
  •     锁机制   Lock

格式:

synchronized(任意对象){
   操作共享数据的代码
}

注意:

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

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

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

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

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

 什么叫代码的同步

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

二,同步方法

格式:

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

 区别:

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

注意:

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

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

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

三,Lock锁 

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

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

  •  void lick()  获得锁
  • void unlock() 释放锁

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

Lock lock = new ReentLock();

死锁:

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

比如:

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

避免:不适用锁的嵌套

生产者消费者

 比如:顾客和厨师

 

线程池的使用:

public class Demo2 {
    public static void main(String[] args) {
        //新建了一个线程任务
        Demo2Runnable demo2Runnable = new Demo2Runnable();
  ExecutorService executorService = Executors.newFixedThreadPool(5);
//submit:将线程任务提交到线程池中   执行线程
        executorService.submit(demo2Runnable);
        executorService.submit(demo2Runnable);
        executorService.submit(demo2Runnable);
        executorService.submit(demo2Runnable);
        executorService.submit(demo2Runnable);
        //关闭线程池
        executorService.shutdown();

    }
}

版权声明:本文为m0_56174436原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。