java回顾之多线程

java回顾之多线程

一、多线程

1、并行与并发

并行:多个事件都在执行,并在某个时刻多个事件是同时执行

并发:多个事件都在执行,但是在某个时刻多个事件没有同时执行。

2、进程与线程

进程:一个进程就是应用程序的一次执行

线程:线程是进程的执行单元。一个进程中可以包含多个线程,一个进程起码有一个线程。

3、Thread类

构造方法:

  Thread() 创建线程对象   Thread(String name) 创建线程对象并指定线程名字

  Thread(Runnable target)  使用Runnable创建线程 

  Thread(Runnable  target,String name)  使用Runable创建线程并指定线程名字

常用方法:

  getName()  获取线程的名字

  start()   开启线程,每个对象只调用一次start

  run()   run方法写线程执行的代码

  sleep() 让当前线程睡指定的时间

  currentThread()    获取当前线程对象

4、创建线程的方法

4.1、继承方式

写一个类,继承Thread类,重写run方法,用start开启线程

4.2、实现方式

创建一个类,实现Runnable接口,重写run方法,run方法写线程执行的代码,然后创建对象,将实现接口的对象作为参数,传入Thread对象中

 

这种方式太麻烦,还可以用匿名内部类的方式,直接将代码写出来

一个是匿名内部类继承Thread类,一个是匿名内部类实现Runable接口

在普通情况下你想用哪种就用哪种。
java中类是单继承的,如果一个类已经有一个父类了,那么只能实现一个接口而不能再去继承一个类。
匿名内部类的方式完全是为了简化代码,你想用就用不想用就不用。、

4.3 callable开启多线程

callable有两个好处,可以写返回值类型,可以抛出异常。

5.安全性问题

线程在高并发的情况下,有安全性问题

1、可见性:一个线程将某个变量的值修改了,但是主线程跑的快,当主线程读取到这个变量的值时,值还没有修改,主线程就会默认这个变量的值不会变量,所以当子线程将值修改后,主线程也没有读取到改变的值

解决这个问题可以使用volatile关键字修饰成员变量,可以解决可见性问题

public static volatile int a = 0;


5.2有序性问题

代码编译期间,代码没有上下的逻辑关系,系统可能出现代码重排的现象,就是会先执行后面的代码再执行前面的代码

这个解决办法也是用volitile关键字

5.3原子性问题

当多个线程修改同一个变量的时候,比如线程一对变量a进行自增,当a=1000的时候,线程一正在修改还没有返回,线程二将a=1000读取走了,这时候线程一将a=1001返回,然后线程二也将a=1001返回,a等于了两回1001

解决原子性问题,第一个方法可以使用原子类来解决

AtomicInteger:对int变量操作的原子类

AtomicLong:对long变量操作的原子类

AtomicBoolean:对boolean变量操作的“原子类”;、

AtomicInteger工作机制-CAS机制

AtomicIntegerArray:原子类数组,解决数组的原子性问题 

多线程的内存机制

 

posted @ 2020-10-16 23:42  springcode  阅读(78)  评论(0编辑  收藏  举报