zoukankan      html  css  js  c++  java
  • 多线程day01

    多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的。

    一.线程的生命周期及五种基本状态

    关于Java中线程的生命周期,首先看一下下面这张较为经典的图:

    上图中基本上囊括了Java中多线程各重要知识点。掌握了上图中的各知识点,Java中的多线程也就基本上掌握了。主要包括:

    Java线程具有五中基本状态

    新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

    就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

    运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就     绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

    阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:

    1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

    2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

    3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

    死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

    二. Java多线程的创建及启动

    【通过继承Thread】

     一个Thread对象只能创建一个线程,即使它调用多次的.start()也会只运行一个的线程。

      【看下面的代码 & 输出结果】

    class CTest extends Thread {
     4     private int tickte = 20;
     5 
     6     public void run() {
     7         while (true) {
     8             if (tickte > 0) {
     9                 System.out.println(Thread.currentThread().getName() + " 出售票 "
    10                         + tickte--);
    11             } else {
    12                 System.exit(0);
    13             }
    14         }
    15     }
    16 
    17 }
    18 
    19 public class Demo3 {
    20     public static void main(String[] args) {
    21         // new CTest().start();
    22         // new CTest().start();
    23         Thread t1 = new CTest();//创建一个线程
    24         t1.start();
    25         t1.start();
    26     }
    27 }
    28 
    29 //
    30 Thread-0 出售票 20
    31 Thread-0 出售票 19
    32 Thread-0 出售票 18
    33 Thread-0 出售票 17
    34 Thread-0 出售票 16
    35 Thread-0 出售票 15
    36 Thread-0 出售票 14
    37 Thread-0 出售票 13
    38 Thread-0 出售票 12
    39 Thread-0 出售票 11
    40 Thread-0 出售票 10
    41 Thread-0 出售票 9
    42 Thread-0 出售票 8
    43 Thread-0 出售票 7
    44 Thread-0 出售票 6
    45 Thread-0 出售票 5
    46 Thread-0 出售票 4
    47 Thread-0 出售票 3
    48 Thread-0 出售票 2
    49 Thread-0 出售票 1

    通过调用当前线程对象的名字Thread.currentThread.getName(),根据结果可以看出,只运行了一个线程

    这就说明了一个问题,每创建一个Thread对象,只能创建一个线程。

    2.实现Runnable接口,并重写该接口的run()方法,该run()方法同样是线程执行体,创建Runnable实现类的实例,并以此实例作为Thread类的target来创建Thread对象,该Thread对象才是真正的线程对象。

    class MyRunnable implements Runnable {
     2     private int i = 0;
     3 
     4     @Override
     5     public void run() {
     6         for (i = 0; i < 100; i++) {
     7             System.out.println(Thread.currentThread().getName() + " " + i);
     8         }
     9     }
    10 }
    public class ThreadTest {
     2 
     3     public static void main(String[] args) {
     4         for (int i = 0; i < 100; i++) {
     5             System.out.println(Thread.currentThread().getName() + " " + i);
     6             if (i == 30) {
     7                 Runnable myRunnable = new MyRunnable(); // 创建一个Runnable实现类的对象
     8                 Thread thread1 = new Thread(myRunnable); // 将myRunnable作为Thread target创建新的线程
     9                 Thread thread2 = new Thread(myRunnable);
    10                 thread1.start(); // 调用start()方法使得线程进入就绪状态
    11                 thread2.start();
    12             }
    13         }
    14     }
    15 }

    3、使用匿名内部类的方式创建线程

    首先回顾下之前的匿名内部类:  

    匿名内部类的格式:
      new 接口或者接口名(){
            重写方法
        };
    本质:是该类或者接口的子类对象

    匿名内部类方式使用多线程
    1、new Thread(){代码…}.start();
    2、new Thread(new Runnable(){代码…}).start();

    例子1:继承Thread类的匿名内部类实现多线程

      // 一、继承Thread类实现多线程
    2         new Thread() {
    3             // 线程的代码
    4             public void run() {
    5                 for (int x = 0; x < 100; x++) {
    6                     System.out.println("Thread" + "--" + x);
    7                 }
    8             }
    9         }.start();// 别忘了启动线程

    例子2:继承Runnable类的匿名内部类实现多线程

      // 二、继承Runnable类实现多线程
     2         new Thread(new Runnable() {
     3             // 线程的代码
     4             public void run() {
     5                 for (int x = 0; x < 100; x++) {
     6                     System.out.println("Runnable" + "--" + x);
     7                 }
     8             }
     9 
    10         })
    11 
    12         {
    13             // 这里的代码为空
    14         }.start();

    由于继承Runnable类实现线程中,start之前的{}为空,这里在继承Thread类中是重写线程的方法的,
     所以,如果两者结合起来的话,会执行Runnable还是Thread?

    例子3:同时继承Runnable类和Thread类的匿名内部类来实现多线程

    // 三、两者结合
     2 
     3         new Thread(new Runnable() {
     4 
     5             public void run() {
     6                 // 填写继承Ruannble的线程代码
     7                 for (int x = 0; x < 100; x++) {
     8                     System.out.println("hello" + "--" + x);
     9                 }
    10 
    11             }
    12 
    13         }) {
    14             // 填写继承Thread类的线程代码
    15             public void run() {
    16                 for (int x = 0; x < 100; x++) {
    17                     System.out.println("world" + "--" + x);
    18                 }
    19             }
    20         }.start();
    21         //通过运行结果可知道,这里只执行继承Thread类的代码
  • 相关阅读:
    推荐系统 蒋凡译 第一章 引言 读书笔记
    神经网络与深度学习 邱锡鹏 第5章 卷积神经网络 读书笔记
    神经网络与深度学习 邱锡鹏 第4章 前馈神经网络 读书笔记
    神经网络与深度学习 邱锡鹏 第3章 线性模型 读书笔记
    神经网络与深度学习 邱锡鹏 第2章 机器学习概述 读书笔记
    神经网络与深度学习 邱锡鹏 第1章 绪论 作业
    神经网络与深度学习 邱锡鹏 第1章 绪论 读书笔记
    算法笔记 上机训练实战指南 第13章 专题扩展 学习笔记
    算法笔记 第13章 专题扩展 学习笔记
    算法笔记 上机训练实战指南 第11章 提高篇(5)--动态规划专题 学习笔记
  • 原文地址:https://www.cnblogs.com/a8457013/p/8074048.html
Copyright © 2011-2022 走看看