Java笔记--多线程【第十三章】

13.1 线程概述
# 概述
  - 多线程使程序可以同时存在多个执行片段,根据不同的条件和环境同步或异步工作
  - 线程与进程的实现原理类似,但服务对象不同
    进程代表操作系统平台中运行的一个程序,而一个程序中将包含多个进程
# 进程
  - 一个包含自身执行地址的程序
  - 多任务操作系统中,把CPU时间分配给每一个程序
  - CPU利用不同时间片段交替执行进程 完成伪同时进行
# 线程
  - 进程内部的多任务操作 [线程]
  - 进程内部的任务称为线程,线程是进程中的实体
  - 线程必须拥有父进程
  - 系统资源:系统不为线程单独分配资 源,线程之间共享进程的系统资源
               共享内存地址空间,即访问相同变量和对象


13.2 线程创建
# 概述
  - 线程也是一种对象
  - 只有实现Runnable接口或继承Thread类的对象才能成为接口

# Thread 类
  · 主要方法:start()、interrupt()、join()、run()
    - start() 启动线程
    - run() 线程的主体方法 [需覆写]
  · 常用构造方法
    - Thread thread = new Thread();
    - Thread thread = new Thread(Runnable simple);
    - Thread thread = new Thread("ThreadName");
    - Thread thread = new Thread(Runnable simple, String name);
  · 代码 -- 继承Thread类 【继承java.lang.Thread类】

    public class SimpleThread extends Thread{
        public SimpleThread(String name){
            setName(name);
        }
        //覆写run()实现用户所需要的功能
        public void run(){ 
            int i = 0;
            while(i++ < 5){
                try{
                    System.out.println(getName() + " 执行步骤 : " + i);
                    Thread.sleep(1000);//休眠1秒
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        }
        //实例化自定义的Thread类,使用start()方法启动线程
        public static void main(String[] args){
            SimpleThread thread1 = new SimpleThread("线程1");
            SimpleThread thread2 = new SimpleThread("线程2");
            
            thread1.start();
            thread2.start();
        }
    }


# Runnable 接口
  · 概念
    - 实现该接口就可以成为线程 [Thread类 因为实现了Runnable接口 所以具有线程接口]
    - Runnable 接口只有一个run()方法 必须覆写
  · 代码 -- 接口实现

  public class SimpleRunnable implements Runnable{
      public void run(){
          int i = 15;
          while(i-- >= 1){
              try{
                    System.out.println(getName() + " 执行步骤 : " + i);
                    Thread.sleep(1000);//休眠1秒
            }catch(Exception e){
                e.printStackTrace();
            }
          }
      }

      public static void mian(String[] args){
          Thread thread1 = new Thread(new SimpleRunnable(), "线程1");
          thread1.start();
      }
  }


13.3 线程的生命周期
# 线程状态:创建、可执行、非可执行、消亡
# 创建
  - 实例化一个thread对象 并执行start()方法之后,线程进入 “可执行”状态,开始执行
  - 同一时间点只有一个线程在执行,转换速度快,看起来像同时执行一样
# 可执行
  - 线程启动start()方法以后,进入可执行状态,执行用户覆写的run()方法
  - 线程进入“可执行”状态,说明加入此应用执行安排的队列中,并不是一直执行到run()结束
  - 何时给与线程执行权,由Java虚拟机和线程的优先级决定
  - 可执行状态:执行完毕 或者 在等待执行权队列中
# 非可执行
  - 使线程离开可执行状态下的等待队列时,进入“非可执行”状态
  - 使用 Thread类中的 wait()、slepp()方法进入“非可执行”状态
  - “非可执行”状态,CPU不分配时间片给这个线程
  - 回到“可执行状态”:notify() interrupt()
# 消亡
  - run()方法执行完毕,线程自动消亡


13.4 线程的优先级
# 优先级范围:1~10 [默认值为5]
            - 可以使用Thread类的setPriority()方法来设定[设定值必为1~10]
# 执行原则:优先级高的线程被优先执行,执行完毕以后才是优先级低的线程执行
            优先权相同,轮流执行
# Time slicing
  - 支持:系统为每个线程分配一小段CPU时间,时间一到换到下一线程 [大部分操作系统系统]
  - 不支持:每个系统执行完毕以后,才执行下一线程
              礼让线程 Thread类 yield()方法


13.5 线程的控制
# 控制方式:启动、挂起、状态检查、正确结束线程 【合理安排线程执行顺序】

# 启动
  - 调用线程start()方法,start()方法告诉系统该线程准备就绪,可以启动run()方法之后返回
    接着继续执行start()方法下面的语句,此时run()方法可能还在继续。

# 挂起
  · 概念:是线程进入“非可执行”状态,此状态下,CPU不分配时间段
           在线程挂起后,可以通过重新唤醒线程使之恢复运行
  · 挂起方法
    - 调用sleep()方法,使线程进入休眠状态,规定休眠时间
    - 调用join()方法,在线程A调用线程B的join()方法,那么线程A被挂起,直到线程B执行完毕
    - 调用wait()方法,使线程挂起,直到线程得到了notify()和notifyAll()消息,进入可执行状态//通信
    - 线程等待某个输入/输出完成
    - suspend() resume()方法,强制挂起

# 检查状态
  - isAlive()方法:测试线程是否处于活动状态,若线程已经启动且尚未终止,则为活动状态

# 结束线程
  · 结束情况
    - 自然消亡:一个线程从run()方法的结尾处返回,自然消亡且不能在被运行
    - 强制死亡:调用Thread类中的stop()方法强制停止 //该方法已被舍弃

# 后台线程 [Deamon线程]
  - 使用Thread类中的setDeamon()方法来设置一个线程为后台线程
  - 必须在线程启动之前调用setDeamon()方法
  - 所有非后台线程结束,那么后台线程也会终止
  - 语法格式:thread.setDeamon(boolean on) // on 为true 则标记为后台线程
  - 判断是否为后台线程:thread.isDeamon()


13.6 线程的同步
# 概述
  - 为避免多线程共享资源时发生冲突,在线程使用资源时给该资源上锁 [同步机制]
  - 共享资源:文件、输入/输出端口、打印机
  - 同步形式:同步方法、同步代码块 [synchronized关键字]
# 同步方法
  - 将访问资源的方法标记为synchronized,
    在调用这个方法的线程执行完之前,其他调用该方法的线程被阻塞
  - 声明
    synchronized void sum(){...}
# 同步代码块
  - 语法格式
    synchronized (someobject){...}

# 产生死锁四条件 [必须同时满足]
  - 互斥条件:资源不共享
  - 请求与保持条件:线程等待资源
  - 非剥夺条件:资源不可被强制剥夺
  - 循环等待条件:A线程等待B,B线程等待A

猜你喜欢

转载自blog.csdn.net/weixin_42358484/article/details/88087075