JAVA基础初探(十四)多线程(线程与进程概述、线程的实现、状态、常用方法、优先级、生命周期)

该篇博客目录、

1、线程与进程概述
2、线程的实现(Thread、Runnable)
3、线程的状态
4、线程常用方法
5、线程优先级
6、线程生命周期图

一、线程与进程概述

1、线程:
- 程序中单独顺序的控制流
- 线程本身依靠程序运行
- 线程是程序中的顺序控制流,只能使用分配给程序的资源和环境
- 线程包含单线程、多线程
2、进程
- 执行中的程序
- 一个进程可以包含一个或多个线程(但至少一个)
3、单线程
- 程序中只存在一个线程,实际上主方法就是一个主线程
4、多线程
- 多线程是在一个程序中运行多个任务
- 多线程的目的是更好的使用CPU资源

二、线程的实现(Thread、Runnable)

JAVA中线程的实现有两种方法
  • 继承Thread类(需要重写Run()方法)
  • 声明实现Runnable接口的类(需要实现Run()方法)
1、继承Thread类

这里写图片描述

  • 需要重写Run()方法
  • 格式

    public class 类名 extends Thread{
    run(){}
    }

例:打印标识是哪个线程在占用CPU资源

继承Thread类__ThreadDemo类

package ThreadDemo;

public class ThreadDemo extends Thread {
    private String name;
    public ThreadDemo(String name) {
        this.name=name;
    }
    @Override
    public void run() {
        for(int i=0;i<1000;i++)
        {
            System.out.println(name+":"+i);
        }
        super.run();
    }
}

测试类Demo

package ThreadDemo;

public class Demo1 {

    public static void main(String[] args) {
        //创建线程
        ThreadDemo t1=new ThreadDemo("A线程");
        ThreadDemo t2=new ThreadDemo("B线程");

        //启动线程
        t1.start();
        t2.start();
    }

}

这里写图片描述

可以看出多线程是并发的,AB线程同时交叉占用CPU资源打印出来

2、声明实现Runnable接口的类

需要实现Run()方法

例:打印标识是哪个线程在占用CPU资源

实现Runnable接口的类
package ThreadDemo;

public class Demo1_Runnable implements Runnable {
    private String name;
    public Demo1_Runnable(String name) {
        this.name=name;
    }
    @Override
    public void run() {
        for(int i=0;i<1000;i++)
        {
            System.out.println(name+":"+i);
        }
    }

}

测试类

package ThreadDemo;

public class Demo1 {

    public static void main(String[] args) {
        //创建线程
        Demo1_Runnable r1=new Demo1_Runnable("A线程");
        Demo1_Runnable r2=new Demo1_Runnable("B线程");

        //Runnable没有启动方法,所以还是需要Thread来启动
        Thread t1=new Thread(r1);
        Thread t2=new Thread(r2);

        //启动线程
        t1.start();
        t2.start();
    }

}

这里写图片描述


三、线程的状态

线程的固定操作状态
  • 创建状态:准备好了一个多线程的对象
  • 就绪状态:调用了start()方法,等待CPU进行调度
  • 运行状态:执行Run()方法
  • 阻塞状态:暂时停止执行,可能将资源交给其他线程使用
  • 终止状态(死亡状态):线程销毁

说明线程也有生老病死的状态


四、线程的常用方法

大多数都在Thread中,所以大部分通过Thread调用

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

public class Demo1_Runnable implements Runnable {
    private String name;
    public Demo1_Runnable(String name) {
        this.name=name;
    }
    @Override
    public void run() {
        for(int i=0;i<1000;i++)
        {
            System.out.println(Thread.currentThread().getName());//获得当前对象,且获取它的名称
        }
    }

}

测试类

package ThreadDemo;

public class Demo1 {

    public static void main(String[] args) {
        //创建线程
        Demo1_Runnable r1=new Demo1_Runnable("A线程");
        Demo1_Runnable r2=new Demo1_Runnable("B线程");

        //Runnable没有启动方法,所以还是需要Thread来启动
        Thread t1=new Thread(r1);
        Thread t2=new Thread(r2);

        //启动线程
        t1.start();
        t2.start();
    }

}

这里写图片描述

isAlive()判断线程是否启动Demo
package ThreadDemo;

public class Demo1_Runnable implements Runnable {
    private String name;
    public Demo1_Runnable(String name) {
        this.name=name;
    }
    @Override
    public void run() {
        for(int i=0;i<10;i++)
        {
            System.out.println(name+":"+i);
        }
    }

}

测试类

package ThreadDemo;

public class Demo1 {

    public static void main(String[] args) {
        //创建线程
        Demo1_Runnable r1=new Demo1_Runnable("A线程");

        //Runnable没有启动方法,所以还是需要Thread来启动
        Thread t1=new Thread(r1);

        //判断线程是否启动
        System.out.println(t1.isAlive());

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

        //判断线程是否启动
        System.out.println(t1.isAlive());
    }

}

这里写图片描述

join()线程的强行运行Demo

因为程序是先运行主线程的,所以想在某时刻运行自己的线程,即可通过join方法

package ThreadDemo;

public class Demo1_Runnable implements Runnable {
    private String name;
    public Demo1_Runnable(String name) {
        this.name=name;
    }
    @Override
    public void run() {
        for(int i=0;i<10;i++)
        {
            System.out.println(name+":"+i);
        }
    }

}

测试类

package ThreadDemo;

public class Demo1 {

    public static void main(String[] args) {
        //创建线程
        Demo1_Runnable r1=new Demo1_Runnable("A线程");    
        //Runnable没有启动方法,所以还是需要Thread来启动
        Thread t1=new Thread(r1);   
        //启动线程
        t1.start();

        for(int i=0;i<20;i++)
        {
            if(i>10)//当i大于10之后运行自己的线程
            {
                try {
                    t1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("主线程:"+i);
        }

    }

}

这里写图片描述

sleep()线程的休眠Demo(进程执行间隔时间)
package ThreadDemo;

public class Demo1_Runnable implements Runnable {
    private String name;
    public Demo1_Runnable(String name) {
        this.name=name;
    }
    @Override
    public void run() {
        for(int i=0;i<10;i++)
        {
            try {
                Thread.sleep(1000);//线程休眠,每次打印间隔时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(name+":"+i);
        }
    }

}

测试类

package ThreadDemo;

public class Demo1 {

    public static void main(String[] args) {
        //创建线程
        Demo1_Runnable r1=new Demo1_Runnable("A线程");    
        //Runnable没有启动方法,所以还是需要Thread来启动
        Thread t1=new Thread(r1);   
        //启动线程
        t1.start();

    }

}

这里写图片描述

yield()线程的礼让Demo

线程的礼让有时候让,有时候不让,是一个可能性的状态

package ThreadDemo;

public class Demo1_Runnable implements Runnable {
    private String name;
    public Demo1_Runnable(String name) {
        this.name=name;
    }
    @Override
    public void run() {
        for(int i=0;i<50;i++)
        {
            System.out.println(name+":"+i);
            if(i==10)
            {
                System.out.println("礼让");
                Thread.yield();//线程的礼让
            }

        }
    }

}

测试类

package ThreadDemo;

public class Demo1 {

    public static void main(String[] args) {
        //创建线程
        Demo1_Runnable r1=new Demo1_Runnable("A线程");    
        Demo1_Runnable r2=new Demo1_Runnable("B线程");
        //Runnable没有启动方法,所以还是需要Thread来启动
        Thread t1=new Thread(r1);   
        Thread t2=new Thread(r2);
        //启动线程
        t1.start();
        t2.start();

    }

}

这里写图片描述

五、线程的优先级

三类优先级


  • MIN_PRIORITY
  • MAX_PRIORITY
  • NORM_PRIORITY

默认是NORM_PRIORITY
Tip:这里优先级设置后,只是提高了该线程先抢到CPU资源的概率,而不是一定能抢到,可以看以下Demo
Demo
package ThreadDemo;

public class ThreadDemo extends Thread {
    private String name;
    public ThreadDemo(String name) {
        this.name=name;
    }
    @Override
    public void run() {
        for(int i=0;i<5;i++)
        {
            System.out.println(name+":"+i);
            try {
                Thread.sleep(1000);
                e.printStackTrace();
            };
        }
        super.run();
    }
}

测试类

package ThreadDemo;

public class Demo1 {

    public static void main(String[] args) {
        //创建线程
        ThreadDemo t1=new ThreadDemo("A线程");    
        ThreadDemo t2=new ThreadDemo("B线程");
        ThreadDemo t3=new ThreadDemo("C线程");

        t1.setPriority(Thread.MIN_PRIORITY);
        t2.setPriority(Thread.MAX_PRIORITY);
        t3.setPriority(Thread.NORM_PRIORITY);

        //启动线程
        t1.start();
        t2.start();
        t3.start();
    }

}

这里写图片描述


六、线程生命周期图

因为该篇博客只是谈谈基础,所以了解一些就大概即可

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值