线程的创建方式


1.继承Thread类

扫地线程类继承Thread类

  1. /**
  2. * 扫地线程
  3. * @author Administrator
  4. *
  5. */
  6. public class SaodiThread extends Thread{
  7. @Override
  8. public void run() {
  9. // TODO Auto-generated method stub
  10. System.out.println("扫地的任务!!!!");
  11. }
  12. }

主方法

  1. public class MainEnter {
  2. /**
  3. * 主方法
  4. * @param args
  5. */
  6. public static void main(String[] args) {
  7. // TODO Auto-generated method stub
  8. System.out.println("主线程开启");
  9. // study01();
  10. study02();
  11. System.out.println("主线程结束");
  12. }
  13. /**
  14. * Thread子类方式
  15. */
  16. private static void study02() {
  17. // TODO Auto-generated method stub
  18. //定义实例
  19. Thread t1 = new SaodiThread();
  20. Thread t2 = new ChaboliThread();
  21. //开启线程
  22. t1.start();
  23. t2.start();
  24. }
  25. /**
  26. * 匿名内部类方案
  27. */
  28. private static void study01() {
  29. // TODO Auto-generated method stub
  30. //默认创建一个线程(匿名内部类)
  31. Thread t1 = new Thread() {
  32. @Override
  33. public void run() {
  34. // TODO Auto-generated method stub
  35. System.out.println("输出" + this.getName());
  36. }
  37. };
  38. Thread t2 = new Thread() {
  39. @Override
  40. public void run() {
  41. // TODO Auto-generated method stub
  42. System.out.println("输出" + this.getName());
  43. }
  44. };
  45. //启动线程
  46. t1.start();
  47. t2.start();
  48. }
  49. }

2.实现Runnable接口

扫地任务类实现Runnable接口

  1. /**
  2. * 扫地任务
  3. * @author Administrator
  4. *
  5. */
  6. public class SaodiTask implements Runnable{
  7. @Override
  8. public void run() {
  9. // TODO Auto-generated method stub
  10. System.out.println("扫地的任务!!!!");
  11. }
  12. }

主方法

  1. private static void study02() {
  2. // TODO Auto-generated method stub
  3. //定义实例(方式一) 此方法与实现类有关
  4. // Thread t1 = new Thread(new SaodiTask());
  5. // Thread t2 = new Thread(new SaodiTask());
  6. //定义实例(方式二) 此方式与实现类无关
  7. Thread t1 = new Thread(() ->{
  8. System.out.println("开启扫地任务");
  9. });
  10. Thread t2 = new Thread(() ->{
  11. System.out.println("开启搽玻璃任务");
  12. });
  13. //开启线程
  14. t1.start();
  15. t2.start();
  16. }

3.两者的比较

1)实现Runnable接口的方式,可以把线程和任务进行分离,更能精准的操作
2)继承Thread类会是该类无法继承其他父类,而实现Runnable接口可以避免这个问题
3)实现Runnable接口的实现类中,不能使用Thread类中的方法

线程的优先级


每个线程在创建时,都有默认的优先级(5),我们也可以设置每个线程的优先级,最大值:10,最小值:1

设置优先级并不能控制线程执行的顺序,改变优先级只是在改变线程被CPU选中执行的概率

​线程的使用 - 图1

  1. public static void main(String[] args) {
  2. // TODO Auto-generated method stub
  3. System.out.println("主线程开启!!!!");
  4. Thread t1 = new Student();
  5. Thread t2 = new Game();
  6. Thread t3 = new Thread(new Video());
  7. //设置线程的优先级()
  8. t1.setPriority(10);
  9. t2.setPriority(6);
  10. t3.setPriority(8);
  11. //启动
  12. t1.start();
  13. t2.start();
  14. t3.start();
  15. //输出线程的优先级
  16. System.out.println(t1.getPriority());
  17. System.out.println(t2.getPriority());
  18. System.out.println(t3.getPriority());
  19. System.out.println("主线程结束!!!!");
  20. }
  21. }

执行结果:

  1. 主线程开启!!!!
  2. 10
  3. 6
  4. 8
  5. 主线程结束!!!!
  6. 我要打游戏!!!!
  7. 看小视频!!!!!
  8. 我要学习!!!

Thread类的常用API


  1. private static void study04() {
  2. // TODO Auto-generated method stub
  3. //定义一个线程,任务:抽烟 线程的名字:蒲老师
  4. Thread t1 = new Thread(()->{
  5. System.out.println("正在执行的任务:抽烟");
  6. },"蒲老师");
  7. //设置优先级
  8. t1.setPriority(8);
  9. System.out.println(t1.getPriority());
  10. //获取线程的ID
  11. System.out.println("线程ID:" + t1.getId());
  12. try {
  13. //休眠5秒钟(时间到了,自动苏醒)
  14. Thread.sleep(5000);//单位是毫秒
  15. } catch (InterruptedException e) {
  16. // TODO Auto-generated catch block
  17. e.printStackTrace();
  18. }
  19. //给线程定义一个名称
  20. // t1.setName("蒲老师");
  21. System.out.println("线程名称:" + t1.getName());
  22. System.out.println("线程的状态:" + t1.getState());
  23. System.out.println("判断线程是否被激活:" + t1.isAlive());
  24. System.out.println("当前正在执行的线程:" + Thread.currentThread());
  25. //开启线程
  26. t1.start();
  27. System.out.println("线程的状态:" + t1.getState());
  28. //关闭线程
  29. t1.interrupt();//t1.stop(); t1.destroy();
  30. //判断线程是否被中断
  31. System.out.println(t1.interrupted());
  32. System.out.println("线程的状态:" + t1.getState());
  33. }

线程的状态


​线程的使用 - 图2

New(新建):创建线程还没有开启的时候
Runnable(就绪):使用start()方法开启线程后,线程状态会从New变成Runnable
Running(执行):被CPU选择,开始执行任务,任务执行结束后,可能会回到Runnable状态继续等待选择
Blocked(阻塞):当线程内部调用sleep()和join()方法时,线程会进入Blocked状态
Dead(死亡):线程执行完毕,死亡

转变状态的方法

1.sleep()

sleep() 方法是 使线程休眠的方法,它将会让线程由Running 变为Blocked 状态,而且它在休眠期间,不会释放任何的线程资源 当休眠时间完毕之后,状态重新变为Runnable

public class StateThread extends Thread{
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i = 1; i <= 100; i ++) {
            for(int j = 1; j <= 10000; j ++) {
                System.out.println(this.getName() + "输出:你好!" + i*j );
            }
            try {
                //休眠3秒钟(被阻塞:线程的状态:由Running 变为Blocked)
                this.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println("子线程执行完毕!!!!");
    }

2.join()

join() 它是一个线程固定抢占CPU的方法,线程只要调用该方法,如果该线程被CPU选中,那么在它的执行时间范围内,CPU都不能被其他线程所持有

 private static void study06() {
        // TODO Auto-generated method stub
        Thread t1 = new StateThread();
        Thread t2 = new StateThread();
        Thread t3 = new StateThread();
        //启动
        t1.start();
        try {
            //join()可以做到,让其他线程等待 被调用join()的线程,执行完毕之后,才可以继续机制
            t1.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        t2.start();
        try {
            //持久CPU的执行时间:为5秒钟
            t2.join(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        t3.start();
    }

3.yield()

yield()方法,是一个可以移交运行权限的方法,它移交运行权利之后,它的状态不像sleep()处于阻塞,它是直接由Running 变成Runnable ,重新抢占CPU的执行权。

public class StateThread extends Thread{
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i = 1; i <= 100; i ++) {
            for(int j = 1; j <= 10000; j ++) {
                System.out.println(this.getName() + "输出:你好!" + i*j );
                //移交当前线程的执行权(并立马可以抢回)
                this.yield();
            }
        }
        System.out.println("子线程执行完毕!!!!");
    }
}