Java多线程

来源:互联网 发布:电影人工智能观后感 编辑:程序博客网 时间:2024/06/07 06:29

一、线程的生命周期

线程的生命周期分为五个状态
1. 新建
2. 就绪
3. 运行
4. 死亡
5. 阻塞
每个状态相应的执行方法请看下图:
image

二、程序、进程、线程的概念

  • 程序:为完成特定任务、用某种语言编写的一组指令的集合。指一段静态的代码,静态对象。
  • 进程:是程序的一次执行过程,或者是正在运行的一个程序,如运行中的播放器。程序是静态的,进程是动态的,它有自己的生命周期
  • 线程:进程可以细化为线程,是程序内部的一条执行路径。(一个程序可以同一时间执行多个线程 )

三、使用多线程的优点

  • 提高应用程序的响应
  • 提高计算机系统的cup的利用率
  • 改善程序结构

四、线程的实现方式

线程的常见时间方式有两种。

  • 继承Thread类,重写run方法
  • 实现Runable接口,重写run方法

五、线程的常用方法

线程的常用方法基本都在Thread中调用

  • 获得线程名称
    getName();
  • 获取当前线程对象
    currentThread();
  • 判断当前线程是否启动
    isAlive();
  • 线程的强行运行
    join();
  • 线程的休眠
    sleep();
  • 线程的礼让
    yield();

六、线程的优先级

默认是5,不绝对是MAX线程先执行。

  • 优先级的顺序设置

    1. MIN_PRIOPRITY
    2. MAX_PRIORITY
    3. NORM_PRIORITY

七、线程同步

同步就是让线程共享资源

  • 同步代码块

    1. 在代码上加上 ‘synchronized’ 关键字

    2. 同步代码块格式:

synchronized(同步对象){    同步代码块;}
  • 同步方法
synchronized public void 方法名称(){}

八、死锁

线程之间相互争夺资源互相不肯释放的情况。
解决办法之一:线程的礼让 yield() (让别的线程执行完在执行本线程)

public class DeadLock {    static StringBuffer sb1 = new StringBuffer();    static StringBuffer sb2 = new StringBuffer();    public static void main(String[] args) {       //线程1        new Thread() {            long start = System.currentTimeMillis();            public void run() {                synchronized (sb1) {                                            sb1.append("A");                    try {                        Thread.currentThread().sleep(10); //让该线程休眠10秒                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    synchronized (sb2) {                        sb2.append("B");                        System.out.println(sb1);                        System.out.println(sb2);                    }                }            }        }.start();            //线程2        new Thread() {            public void run() {                synchronized (sb2) {                    sb1.append("C");                    synchronized (sb1) {                        sb2.append("D");                        System.out.println(sb1);                        System.out.println(sb2);                    }                }            }        }.start();    }}Thread1-->sb1   //线程一持有sb1对象锁sleep(10);      //休眠的过程中可能被其他线程占据了资源Thread1-->sb2   //线程一持有sb2对象所失败(因为被其他线程占据了资源,不能够往下执行)Thread2-->sb2   //线程二持有sb2对象锁Thread2-->sb1   //线程二持有sb1对象锁失败,原因是该对象锁被线程一持有二没有释放资源。通过上面的步骤产生了死锁的现象,即不同的对象分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源。
  • 死锁的必要条件

    1. 互斥条件:一个资源每次只能被一个进程使用;
    2. 请求与保持条件:一个进程因请求资源阻塞时,对已获得的资源不释放;
    3. 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺;
    4. 循环等待条件:若干进程之间形成一种头尾相接循环等待资源关系。
  • 死锁的预防

    1. 可剥夺资源(破坏不剥夺条件)
    2. 资源一次性分配(破坏请求与保持条件):新进程未满足条件时,释放资源
    3. 资源有序分配法(破坏循环等待条件)
  • 死锁的避免

银行家算法

  • 死锁的检测

给每个进程和资源分配唯一编号,然后建立资源分配表和进程等待表

  • 死锁的解除

    1. 剥夺资源:从其他进程剥夺资源给死锁进程、以解除死锁状态
    2. 撤销进程:可以直接撤消死锁进程或撤消代价最小的进程,直至有足够的资源可用,死锁状态.消除为止;所谓代价是指优先级、运行代价、进程的重要性和价值等。

九、线程池

  • 概念

线程池实现了一个java高并发、多线程的、可管理统一调度器,减少线程的创建和销毁对象的次数。

  • 线程池的优点

    1. 降低资源的消耗:降低创建线程和销毁线程的消耗。
    2. 提高响应速度:当任务达到时,任务不需要创建线程就可以执行。
    3. 提高线程的可管理性:避免无线创建线程、统一对线程进行调度。
原创粉丝点击