一.进程与线程

  1. 进程:每一个独立运行的程序称为一个进程

  2. 线程:线程时一个进程内部的一条执行路径,Java虚拟机允许程序并发的运行多个执行路径

    *进程中执行运算的最小单位——>线程<——处理机分配

  3. 进程与线程的区别:

    (1)进程有独立的运行地址空间,一个进程崩溃后不会影响到其他的进程,而线程只是 一个进程中的一个执行路径,如果有一条线程奔溃了,可能会影响到进程中的的其他线程

    (2)线程有自己的栈和局部变量,多个线程共享同一进程的地址空间

    (3)一个进程至少有一个线程

  4. 多线程

    (1)多线程 就是在一个进程中创建多个线程,每个线程完成一个任务

    (2)优点:

    <1>多线程技术使程序的响应速度更快

    <2>提高资源利用率

    <3>程序设计更加简单

  5. 多线程的执行特性

    (1)随机性(一部执行):谁“抢”到CPU,谁执行

    (2)宏观上同时执行,微观上同一时刻只能执行一个线程(多核除外)

    二.线程的创建和启动

    1.两种创建 新线程的方式

    <1>第一种方式:将类声明为Thread的子类并重写run()方法

    格式:

    class MygThread extends Thread{

    Public void run(){

    线程具体执行代码

    }

    }

    创建此线程类的实例并启动:

    MyThread thread1=new MyThread()

    Thread1.start();  //启动线程

    2.线程的基本使用方法

    (1)public void start():是该线程开始执行

    (2)public static Thread currentThread(): 返回对当前正在执行的线程对象的引用

    (3)public final void seetName(String str):改变线程名称

    (4)public final void setDDeamon(boolean  on):将该线程标记为守护线程或用户线程

    (5)public static void sleep(long millis):线程休眠指定毫秒数

    (6)public final void join():当前线程必须等待,直到调用join()方法的线程对象所对应的线程运行完毕,当前线程才恢复执行

    (7)public static void yield():线程礼让,但操作系统可以忽略这个礼让请求

    1(以创建线程为例):

    创建线程:

    package thread;

     

    public class ThreadDemo extends Thread {

     

        public ThreadDemo() {

     

        }

     

        public ThreadDemo(String name) {

            super(name);

        }

     

        @Override

        public void run() {

            for (int i = 0; i < 10; i++) {

                System.out.println(Thread.currentThread().getName()+"循环输出i="+i);

        }

        super.run();

        }

    }

    实例化线程测试:

    package thread;

     

    public class ThreadTest {

     

        public static void main(String[] args) {

            ThreadDemo thread=new ThreadDemo("线程A——>");

            thread.start();

            ThreadDemo thread1=new ThreadDemo("线程B——>");

            thread1.start();

        }

     

    }

    运行结果:

    线程A——>循环输出i=0

    线程B——>循环输出i=0

    线程A——>循环输出i=1

    线程A——>循环输出i=2

    线程A——>循环输出i=3

    线程B——>循环输出i=1

    线程A——>循环输出i=4

    线程B——>循环输出i=2

    线程B——>循环输出i=3

    线程A——>循环输出i=5

    线程B——>循环输出i=4

    线程A——>循环输出i=6

    线程B——>循环输出i=5

    线程A——>循环输出i=7

    线程B——>循环输出i=6

    线程A——>循环输出i=8

    线程B——>循环输出i=7

    线程B——>循环输出i=8

    线程A——>循环输出i=9

    线程B——>循环输出i=9

    2(以线程中的休眠方法为例):

    创建线程:

    package thread;

     

    public class ThreadDemo extends Thread {

     

    public ThreadDemo() {

     

    }

     

    public ThreadDemo(String name) {

    super(name);

    }

     

    @Override

    public void run() {

    for (int i = 0; i < 10; i++) {

    System.out.println(Thread.currentThread().getName()+"循环输出i="+i);

    }

    super.run();

    }

    }

    测试休眠方法:

    package thread;

     

    public class ThreadTest {

     

    public static void main(String[] args) {

    ThreadDemo thread=new ThreadDemo("线程A——>");

    thread.start();

    ThreadDemo thread1=new ThreadDemo("线程B——>");

    thread1.start();

    for (int i = 0; i < 10; i++) {

    try {

    Thread.sleep(1000);//当前线程休眠1000ms

    } catch (InterruptedException e) {

    System.out.println("捕获到的已常为:"+e.getMessage());

    }

    System.out.println(Thread.currentThread().getName()+"线程——>i="+i);

    }

    }

     

    }

    运行结果:

    线程A——>循环输出i=0

    线程A——>循环输出i=1

    线程A——>循环输出i=2

    线程A——>循环输出i=3

    线程A——>循环输出i=4

    线程A——>循环输出i=5

    线程A——>循环输出i=6

    线程A——>循环输出i=7

    线程A——>循环输出i=8

    线程A——>循环输出i=9

    main线程——>i=0

    main线程——>i=1

    main线程——>i=2

    main线程——>i=3

    main线程——>i=4

    main线程——>i=5

    main线程——>i=6

    main线程——>i=7

    main线程——>i=8

    main线程——>i=9

    当前线程运行所用时间:10s

    3(以线程中的join方法为例):

    创建线程类:

    package thread;

     

    public class ThreadDemo extends Thread {

     

    public ThreadDemo() {

     

    }

     

    public ThreadDemo(String name) {

    super(name);

    }

     

    @Override

    public void run() {

    for (int i = 0; i < 20; i++) {

    System.out.println(Thread.currentThread().getName()+"循环输出i="+i);

    }

    super.run();

    }

    }

    测试join()方法类:

    package thread;

     

    public class ThreadModth {

    public static void main(String[] args){

    ThreadDemo thread=new ThreadDemo("线程一——>");

    thread.start();

    for (int i = 1; i < 20; i++) {

    if(i==10){

    try {

    thread.join();//当前线程休眠, 直到调用join方法的线程 执行完毕,当前线程开始执行

    } catch (InterruptedException e) {

    System.out.println("捕获到的异常为:"+e.getMessage());

    }

    }

    System.out.println(Thread.currentThread().getName()+"线程——>i="+i);

    }

    }

     

    }

    运行结果:

     main线程——>i=1

    main线程——>i=2

    线程一——>循环输出i=0

    main线程——>i=3

    线程一——>循环输出i=1

    main线程——>i=4

    线程一——>循环输出i=2

    main线程——>i=5

    线程一——>循环输出i=3

    main线程——>i=6

    线程一——>循环输出i=4

    main线程——>i=7

    线程一——>循环输出i=5

    main线程——>i=8

    线程一——>循环输出i=6

    main线程——>i=9

    线程一——>循环输出i=7

    线程一——>循环输出i=8

    线程一——>循环输出i=9

    线程一——>循环输出i=10

    线程一——>循环输出i=11

    线程一——>循环输出i=12

    线程一——>循环输出i=13

    线程一——>循环输出i=14

    线程一——>循环输出i=15

    线程一——>循环输出i=16

    线程一——>循环输出i=17

    线程一——>循环输出i=18

    线程一——>循环输出i=19

    main线程——>i=10

    main线程——>i=11

    main线程——>i=12

    main线程——>i=13

    main线程——>i=14

    main线程——>i=15

    main线程——>i=16

    main线程——>i=17

    main线程——>i=18

    main线程——>i=19

    二.线程的生命周期(状态转换)

    1.线程的状态

    2.要想实现多线程,必须在主线程中创建新的线程对象,任何线程都具有五种状态:创建,就绪,运行,阻塞,终止

    状态图:

     Java总结(九)——(线程模块 一(线程的创建(方法一)与启动,线程状态与生命周期,进程与线程))_启动

    3.线程的停止

    (1)如果线程的run()方法中执行的是一个重复执行的循环,可以提供一个标记来控制循环是否执行吧

    (2)如果线程因为执行sleep()方法或是wait()方法而进入了阻塞状态,此时想要停止它,可以使用interrupt(),程序会抛出InterruptException异常

    (3)如果程序因为输入输出的等待而阻塞,基本上 必须等待输入输出动作完成后才能离开阻塞状态,无法用interrupt() 方法来使线程离开run()方法,要想离开,只能通过引发一个异常

    1.(停止循环线程)

    创建循环线程:

    package stopthread;

     

    public class LoopThread extends Thread{

    private boolean flag=true;//设置线程停止标志

     

    public void setFlag(boolean flag) {

    this.flag = flag;

    }

     

    @Override

    public void run() {

    while(flag){

    System.out.println("当前 线程正在运行....");

    }

    }  

    }

    测试停止循环线程:

    package stopthread;

     

    public class StopLoop {

     

    public static void main(String[] args) {

    long startTime= System.currentTimeMillis();//开始线程时间

    LoopThread lt=new LoopThread();

    lt.start();

    try {

    Thread.sleep(3000);//当前线程休眠3000ms

    } catch (InterruptedException e) {

    System.out.println("捕获到的异常为:"+e.getMessage());

    }

    lt.setFlag(false);

    System.out.println("end............");

    long destTime=System.currentTimeMillis();//结束线程时间

    System.out.println("执行完线程共用时间:"+(destTime-startTime)/1000+"s");

    }

     

    }

    运行结果:

    当前 线程正在运行....

    当前 线程正在运行....

    当前 线程正在运行....

    当前 线程正在运行....

    当前 线程正在运行....

    当前 线程正在运行....

    当前 线程正在运行....

    当前 线程正在运行....

    当前 线程正在运行....

    当前 线程正在运行....

    当前 线程正在运行....

    ...................

    ...................

    end............

    执行完线程共用时间:3s

    2.(以中断休眠为例 )

    创建休眠中断线程:

    package stopthread;

     

    public class InterruptThread extends Thread{

    private String name;

     

    public InterruptThread(String name) {

    super(name);

    this.name = name;

    }

     

    @Override

    public void run() {

    System.out.println(Thread.currentThread().getName()+"开始执行");

    System.out.println("准备休息5s");

    long startTime=System.currentTimeMillis();// 线程开始时间

    try {

    Thread.sleep(5000);

    } catch (InterruptedException e) {

    System.out.println("为什么要叫醒我?");

    }

     long destTime=System.currentTimeMillis();//线程完毕时间

    System.out.println(Thread.currentThread().getName()+"执行完毕");

    System.out.println("执行线程所用时间:"+(destTime-startTime)/1000+"s");

     

    }

    }

    测试终端休眠:

    package stopthread;

     

    public class StopInterrupt {

     

    public static void main(String[] args) {

    InterruptThread it=new InterruptThread("线程一——>");

    it.start();

    try {

    Thread.sleep(2000);//当前线程休眠2000ms

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    it.interrupt();//打断这个线程,使之抛出InterruptedException异常

    }

     

    }

    运行结果:

    线程一——>开始执行

    准备休息5s

    为什么要叫醒我?

    线程一——>执行完毕

    执行线程所用时间:2s