一、JAVA如何开启线程?怎么保证线程安全?
线程跟进程的区别:进程是操作系统进行资源分配的最小单元。线程是操作系统进行任务分配的最小单元,进程隶属于线程
如何开启线程?
1.继承Thread,重写run方法;2.实现Runnable接口,实现run方法(常用)
3.实现Callable接口,实现call方法。通过FutureTask创建一个线程,获取到线程执行的返回值;4.通过线程池来开启线程。
怎么保证线程安全?核心:加锁
如何加锁:1.使用JVM提供的锁,也就是Synchronized关键字;2. JDK提供的各种锁lock
二.Volatile和Synchronized有什么区别?Volatile能不能保证线程安全?DCL(Double Check Lock)单例为什么要加Volatile?
-
Synchronized关键字用来加锁,Volatile只是保持变量的线程可见性。通常适用于一个线程写多个线程读的场景
-
不能,Volatile关键字只能保证线程可见性,不能保证原子性
public class VolatileDemo2 { public static /*volatile*/ boolean flag = true; public static void main(String[] args) { new Thread(()->{ while(flag){ } System.out.println("========End of Thread1========="); }).start(); try { Thread.sleep( millis: 100); }catch (InterruptedException e) { e.printStackTrace(); } System.out.println("turn flag off"); flag=false; } }
Volatile能使线程的改变立马传递给其他线程,保证可见性
3.作用 Volatile防止指令重排。在DCL中,防止高并发情况下指令重排造成的线程安全问题
指令重排:指在cup中 先分配内存 再初始化 再建立指针关系 多线程中当指针初始化过程中另一个线程访问,则会导致线程安全出现问题
public class SingleDemo1{ // private static SingleDemo1 singleDemo1=new SingleDemo1(); private static SingleDemo1 singleDemo1; private SingleDemo1(){ }