1.多线程前置知识点

1.什么是进程,线程,程序

我们需要了解进程,线程,程序三者的关系:
程序:是为了完成特定任务,用某种语言编写的一组指令的集合,是一段静态的代码(程序是静态的)
进程:是程序的一次执行过程,是正在执行的一个程序.进程作为资源分配的单位,在内存中,会为每个进程分配不同的内存区域.进程是动态的,是一个动的过程,进程的生命周期:有他自身的产生,存在和消亡的过程.
线程:进程可进一步细化为线程,是一个程序内部的一条执行路径.,若一个进程同一时间并行执行多个线程,就是支持多线程的.

以前的单核cpu:
image.png
现在的多核cpu:
image.png

2.什么是并行和并发?

并行:多个cpu同时执行多个任务
并发:一个cpu“同时”执行多个任务(采用时间片切换)

2.初入多线程

1.实现多线程的第一种方式:
实现Thread类,这个类中有一个run方法,这个方法就是线程执行的方法,我们可以通过调用start方法来执行这个run方法。

2.实现多线程的第二种方式
实现Runnable类,这个类中有一个run方法,这个方法就是线程执行的方法,我们可以通过调用start方法来执行这个run方法。
这两种方式实现的多线程缺点:
实现线程的方式无返回值,不能 抛出异常

3.实现多线程的第三种方式
实现Callable接口:jdk5之后出现的
为什么要实现Callable接口:
因为实现Callable接口实现线程的方式可以有返回值,可以抛出异常。
缺点:线程的创建比较麻烦

  1. /**
  2. * @Author Rookie Coder
  3. * @Description 实现Callable接口
  4. * @Date
  5. **/
  6. public class TestCallable implements Callable {
  7. @Override
  8. public Object call() throws Exception {
  9. return Math.random()*10;
  10. }
  11. }
  12. class MyTest{
  13. public static void main(String[] args) throws ExecutionException, InterruptedException {
  14. TestCallable testCallable = new TestCallable();
  15. FutureTask ft = new FutureTask(testCallable);
  16. Thread th = new Thread(ft);
  17. th.start();
  18. // 获取返回值
  19. Object o = ft.get();
  20. System.out.println(o);
  21. }
  22. }

4.多线程常用的一些方法
1.start():启动当前线程,内部调用当前线程的run方法
2.run():线程执行的方法,将创建的线程操作声明在此方法中
3.currentThread():静态方法,返回执行当前代码的线程
4.getName():获取当前线程的名字
5.setName():设置线程的名字
6.yield():释放当前cpu的执行权,但是有可能栽下一刻再次抢到此线程
7.join():当前线程阻塞,直到下一个抢到cpu执行权的线程执行完之后,此线程才会被激活重新进入就绪状态。
8.sleep():当前线程睡眠,直到

5.线程的生命周期

image.png

  • 线程安全问题:

    • 1.问题:买票过程中,出现了重票,错票
    • 2.称作线程安全问题
    • 3.问题出现的原因:当某个线程操作车票的过程中,尚未完成操作之前,有别的
      1. 线程又进来了,同时来操作这个共享数据,因此出现了线程安全问题
      1. 4.怎么解决:
      1. 当一个线程在操作共享数据的时候,其他线程不能参与进来,直到线程a操作完ticket时,
      1. 其他线程才可以开始操作,这种情况即使线程a出现了阻塞, 也不能改变这个状况
      1. 5.java中,我们通过同步机制来解决线程的安全问题
      1. 方式1:同步代码快
      1. synchronized(同步监视器){
      1. 需要被同步的代码
      1. }
      1. 说明:操作共享数据的代码即为需要被同步的代码
      1. 共享数据:多个线程共同操作的变量,比如ticket就是共享数据
      1. 同步监视器,俗称锁,任何一个类的对象都可以充当锁。
      1. 要求:多个线程必须要公用同一把锁
      1. 方式2:同步方法
      1. 关键字 完整的声明到方法处

多线程常见问题:
1.画图说明线程的声明周期,以及各状态切换使用到的方法等
如上
2.同步代码快中涉及到同步监视器和共享数据,谈谈你对同步监视器和共享数据的理解,以及注意点
同步监视器
共享数据:多个线程同时要操作的数据叫做共享数据,比如,我们多个人要对同一个账户进行转账操作,时这个账户就是一个共享数据
3.sleep和wait的区别
sleep:一旦执行此方法,线程就会进入阻塞状态,
wait:一旦执行此方法当前线程就进入阻塞状态,并释放同步监视器
notify:一旦执行此方法,就会唤醒一个被wait的线程,如果有多个线程被wait,唤醒优先级最高的,如果优先级一样,就随机唤醒
notifyAll:唤醒所有线程。

sleep和wait的异同点:
相同点:sleep和wait都会使线程进入阻塞状态,、
不同点:sleep是Thread类中的静态方法,wait是object中的方法
sleep只要想掉用可以在方法的任何地方使用Thread来调用
wait必须要在同步方法或者同步代码块中调用
sleep()不会释放锁,wait会释放锁

4.写一个线程安全的懒汉式
5.创建多线程有哪几种方式
4种
image.png
image.png