多线程

来源:互联网 发布:h3c网络工程师证书知乎 编辑:程序博客网 时间:2024/06/12 00:12

一、线程的状态

二、创建线程的方式

1、继承Thread类

2、实现 Runnable接口

2.1、定义类实现Runnable接口

2.2、覆盖接口中的run方法,将线程的任务代码封装到run方法中

2.3、通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递

                   为什么? 因为线程的任务都封装在Runnable接口子类对象的run方法中,所以要在线程对象创建时就必须明确要运行的任务

2.4、调用线程对象的start方法开启线程

三、实现Runnable接口的好处

3.1、将线程的任务从线程的子类中分离出来,进行了单独的封装。按照面向对象的思想将任务封装成对象

3.2、避免了java单独继承的局限性

创建线程较常用的方式为 implements Runnable 接口

四、线程安全问题

4.1、线程安全问题产生的原因:

         多个线程在操作共享的数据

         操作共享数据的线程代码的多条

当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。

4.2、同步代码块

         同步代码块中的对象代表什么?

4.3、同步函数与同步代码块的区别

         同步函数的锁是固定的this

         同步代码块的锁是任意的对象

         (建议使用同步代码块)

4.4、静态同步函数的锁

         该函数所属字节码文件对象 可以用this.class

4.5、单例模式涉及的多线程问题

五、线程间通信

         多个线程在处理同一资源,但是任务却不同

5.1、等待唤醒机制

         涉及的方法:

         1、wait():让线程处于冻结状态,被wait的线程会被存储到线程池中

         2、notify():唤醒线程池中一个线程(任意)

         3、notifyAll():唤醒线程池中的所有线程

    这些方法都必须定义在同步中,因为这些方法是用于操作线程状态的方法,必须要明确到底操作的是哪个锁上的线程

    为什么操作线程的方法wait、notify、notifyAll定义在了Object类中? 因为这些方法是监视器的方法,监视器其实就是锁,锁可以是任意对象,任意的对象调用的方式一定定义在Object类中。

5.2、多生产者多消费者问题

         if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。

         while判断标记,解决了线程获取执行权后,是否要运行

         notify只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+ notify会导致死锁

         notifyAll解决了本方线程一定会唤醒对方线程的问题

5.3、JDK1.5新特性 Lock

         将同步和锁封装成了对象,并将操作锁的隐式方式定义到了该对象中,将隐式动作变成了显示动作。

5.4、JDK1.5新特性Condition

六、wait与sleep的区别

6.1、wait可以指定时间也可以不指定

         sleep必须指定时间

6.2、在同步中时,对CPU的执行权和锁的处理不同

         wait:释放执行权,释放锁

         sleep:释放执行权,不释放锁

七、停止线程方式

         1、stop方法

         2、run方法结束

                   怎么控制线程的任务结束?任务中都会有循环结构,只要控制住循环就可以结束任务。控制循环通常就用定义标记来完成。

7.1、定义标记

7.2、Interrupt

         但是如果线程处于了冻结状态,无法读取标记。如何?

八、守护线程(setDaemon)

九、其他方法

9.1、join

0 0
原创粉丝点击