java多线程知识进阶

添加链接描述
@TOC

synchronized关键字

对synchronized关键字的了解

synchronized块是Java提供的原子性内置锁,Java中的每个对象都可以将其当作一个同步锁来使用,Java内置的、使用者看不到的锁称为内部锁,也叫监视器锁。线程的执行代码在进入synchronized代码块前会自动获取内部锁,这时其他线程访问该代码块会被阻塞挂起。内置锁是排他锁,其他线程必须等待该线程释放锁后才能获取该锁。
另外,Java中的线程与操作系统的原生线程是一一对应的,当阻塞一个线程时,需要从用户态切换到内核态进行阻塞操作,这很耗时,而synchronized的使用会导致上下文切换。

如何使用该关键字

同步代码块之前,获取对同步监视器的锁定

该关键字的底层细节

进入synchronized块的内存语义是把synchronized块内使用到的变量从线程的工作内存中清除,这样synchronized块用到该变量时不会从线程的工作内存中获取,而是直接从主存中获取,退出synchronized块是把synchronized块内的共享变量的修改刷新到主存中。

synchronized与 ReentrantLock 关键字的区别

volatile关键字

java内存模型

volatile与synchronized的区别

使用锁会带来线程上下文切换的问题,影响效率。java提供volatile关键字,这是一种弱形式的同步,可以确保一个变量的更新对其他变量可见。当一个变量被声明为volatile时,线程在写入变量时会将值刷新回主内存。当其他线程读取该共享变量时,从主内存中获取最新值。

ThreadLocal

简介

ThreadLocal是JDK提供的工具类,它提供了线程本地变量。当创建ThreadLocal变量时,访问这个变量的每个线程都会有这个变量的本地副本,当多个线程操作这个变量时,实际上操纵的是变量的本地副本,从而避免了线程安全问题。

原理

java多线程知识进阶_第1张图片
如图所示,Thread类有threadLocals和inheritableThreadLocals,都属于ThreadLocalMap类型的变量,ThreadLocalMap为定制化的HashMap。默认两个变量为null。ThreadLocal类型的本地变量存放在具体的线程内存空间中。ThreadLocal为工具壳,通过set方法把value值放入调用线程的threadLocals中存放起来,当调用get时再拿出来使用。不需要使用本地变量时,调用ThreadLocal的remove方法从线程的threadLocals中删除本地变量。
threadLocals设计为map结构是为了关联多个threadLocal变量。

线程池

为什么使用线程池

线程池在创建时就创建了大量的空闲的线程,程序将Runnable或Callable对象传递给线程池时,线程池启动一个线程来完成Run或call任务,完成后线程不死亡,而是返回线程进入空闲状态。等待下一个runnable对象的run()方法和call()方法。

  1. 执行大量的异步任务时能提供比较好的性能,线程的创建开销很大,线程池内线程可以复用
  2. 线程池提供了一种资源限制和管理的手段,可以有效地控制系统中并发线程的数量。

实现Runnable和Callable的区别

通过继承Thread类或实现Runnable、callable接口都可以实现多线程,Runnable与callable接口的方式基本上相同,Callable接口定义的方法里有返回值,可以声明抛出异常。

使用Runnable和Callable接口的好处

  1. 线程类只是实现了接口,还可以集成其他的类
  2. 多个线程可以共享同一个target对象,适合多个线程处理同一份资源的情况。
  3. 需要访问当前线程时,需要使用Thread.currentThread()方法

你可能感兴趣的:(java,多线程)