java线程状态和线程调度

旧城等待, 2022-08-31 09:46 348阅读 0赞

java线程的创建和启动

文章目录

  • 多线程
      • 线程的状态
      • 线程调度
          • 线程优先级
          • 线程休眠
          • 阻塞线程
          • 线程礼让
          • 线程调度练习

多线程

线程的状态

Java 线程状态、线程池状态\_shadow\_zed的博客-CSDN博客\_java 线程池的状态

  1. package Threads;
  2. public class MyThread5 implements Runnable {
  3. @Override
  4. public void run() {
  5. System.out.println("线程正在运行,处于运行状态");
  6. try {
  7. System.out.println("线程开始休眠,处于阻塞状态");
  8. //线程休眠5S
  9. Thread.sleep(5000);
  10. System.out.println("线程休眠结束,阻塞状态结束,再次进入就绪状态");
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. System.out.println("线程中断");
  14. }
  15. }
  16. }
  17. package Test;
  18. import Threads.MyThread5;
  19. //测试线程的状态
  20. public class MyThread5Test {
  21. public static void main(String[] args) {
  22. Runnable runnable = new MyThread5();
  23. Thread t = new Thread(runnable);
  24. System.out.println("线程处于创建状态");
  25. t.start();
  26. System.out.println("线程处于就绪状态");
  27. }
  28. }

线程调度

线程优先级

由于线程之间的运行是通过抢占CPU的资源来进行的,线程调度指的是按照特定的机制为多个线程分配CPU的使用权。
请添加图片描述

线程的优先级由1-10表示,1表示最低,10最高,默认的优先级是5。优先级高的线程获得CPU的资源概率比较大.

尝试更改线程的优先级:

  1. package Threads;
  2. //创建线程类,实现Runnable接口
  3. public class MyThread2 implements Runnable {
  4. @Override
  5. public void run() {
  6. for (int i = 1; i <= 100; i++) {
  7. System.out.println(Thread.currentThread().getName() + ":" + i);
  8. }
  9. }
  10. }
  11. package Test;
  12. import Threads.MyThread2;
  13. //测试线程
  14. public class MyThread2Test {
  15. public static void main(String[] args) {
  16. //创建线程对象
  17. Runnable runnable = new MyThread2();
  18. Thread thread = new Thread(runnable, "mythread1");
  19. Thread thread1 = new Thread(runnable, "mythread2");
  20. //线程调度,设置线程优先级
  21. // thread1.setPriority(10);
  22. // thread.setPriority(1);
  23. thread1.setPriority(Thread.MAX_PRIORITY);
  24. thread.setPriority(Thread.MIN_PRIORITY);
  25. //启动线程
  26. thread.start();
  27. thread1.start();
  28. }
  29. }
线程休眠

线程调度的另一个方案是线程休眠。让线程展示睡眠指定的时长,线程会进入到阻塞状态,睡眠时间过后的线程会再进入可运行的状态。

方法是:

public static void sleep(long millis)

millis是休眠时长,以毫秒为单位,调用sleep()方法需要处理InterruptedException异常。

  1. package Threads;
  2. //模拟线程休眠的过程
  3. public class Wait {
  4. public static void bySec(long s) {
  5. for (int i = 1; i <= 5; i++) {
  6. System.out.println(i+"秒");
  7. try {
  8. Thread.sleep(1000);
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. }
  13. }
  14. public static void main(String[] args) {
  15. System.out.println("线程开始休眠");
  16. Wait.bySec(5);
  17. System.out.println("线程结束休眠");
  18. }
  19. }
阻塞线程
  • join()方法
    等待该线程终止,等待加入的其他线程结束后在继续执行本线程

    package Threads;

    public class MyThread6 implements Runnable {

    1. @Override
    2. public void run() {
    3. for (int i = 1; i <= 30; i++) {
    4. System.out.println(Thread.currentThread().getName() + ":" + i);
    5. }
    6. }

    }

    package Test;

  1. import Threads.MyThread6;
  2. public class MyThread6Test {
  3. public static void main(String[] args) {
  4. //创建子线程对象t
  5. Runnable runnable = new MyThread6();
  6. Thread t = new Thread(runnable, "myThread");
  7. t.start();
  8. //主线程main做的事情
  9. for (int i = 1; i <= 20; i++) {
  10. System.out.println(Thread.currentThread().getName() + ":" + i);
  11. //当i = 5的时候,强制把t线程加入执行
  12. //线程调度:join()--等待线程终止,等待t线程执行结束后,main主线程再继续执行
  13. if (i == 5) {
  14. try {
  15. t.join();
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. }
  21. }
  22. }
线程礼让
  • yield()方法

暂停当前线程,允许其他具有相同优先级的线程获得运行机会,该线程处于就绪状态,不会转为阻塞状态。这是线程之间的礼让问题,只是提供一种可能,但是不能保证一定会礼让成功。

  1. package Threads;
  2. public class MyThread7 implements Runnable {
  3. @Override
  4. public void run() {
  5. for (int i = 0; i <= 4; i++) {
  6. System.out.println(Thread.currentThread().getName() + ":" + i);
  7. if (i == 3) {
  8. Thread.yield();
  9. }
  10. }
  11. }
  12. }
  13. package Test;
  14. import Threads.MyThread7;
  15. public class MyThread7Test {
  16. public static void main(String[] args) {
  17. Runnable runnable = new MyThread7();
  18. Thread t1 = new Thread(runnable, "线程A");
  19. Thread t2 = new Thread(runnable, "线程B");
  20. t1.start();
  21. t2.start();
  22. }
  23. }
线程调度练习
  • 优先级问题

    package Threads;

    public class MyThread8 implements Runnable {

    1. @Override
    2. public void run() {
    3. }

    }

    package Test;

    import Threads.MyThread8;

    //获取和设置主线程和子线程的优先级
    public class MyThread8Test {

    1. public static void main(String[] args) {
    2. //主线程
    3. Thread mainThread = Thread.currentThread();
    4. //子线程
    5. Thread myThread = new Thread(new MyThread8());
    6. System.out.println("默认的优先级");
    7. System.out.println("主线程名:" + mainThread.getName() + "优先级:" + mainThread.getPriority());
    8. System.out.println("子线程名:" + myThread.getName() + "优先级:" + myThread.getPriority());
    9. System.out.println("修改优先级后");
    10. mainThread.setPriority(Thread.MAX_PRIORITY);
    11. myThread.setPriority(Thread.MIN_PRIORITY);
    12. System.out.println("主线程名:" + mainThread.getName() + "优先级:" + mainThread.getPriority());
    13. System.out.println("子线程名:" + myThread.getName() + "优先级:" + myThread.getPriority());
    14. }

    }

  • 练习

    需求:某一个科室一天需看普通号20个,特需号10个,特需号的看病时间是普通号的2倍。开始时普通号和特需号并行叫号,叫到特需号的概率比普通号的高。当普通号叫完第10号时,要求先看完全部的特需号再看普通号。

    package Threads;

    public class SpecialThread implements Runnable {

    1. @Override
    2. public void run() {
    3. for (int i = 1; i <= 10; i++) {
    4. System.out.println("特需号:" + i + "号病人正在看病");
    5. //线程休眠来表示看病的过程
    6. try {
    7. Thread.sleep(1000);
    8. } catch (InterruptedException e) {
    9. e.printStackTrace();
    10. }
    11. }
    12. }

    }

    package Threads;

    //模拟医院看病
    public class CommonThread {

    1. public static void main(String[] args) {
    2. //当前线程--普通号
    3. //创建一个特需号的线程
    4. Thread special = new Thread(new SpecialThread());
    5. special.setPriority(Thread.MAX_PRIORITY);
    6. special.start();
    7. for (int i = 1; i <= 20; i++) {
    8. System.out.println("普通号:" + i + "号病人在看病");
    9. try {
    10. Thread.sleep(500);
    11. } catch (InterruptedException e) {
    12. e.printStackTrace();
    13. }
    14. if (i == 10) {
    15. try {
    16. special.join();
    17. } catch (InterruptedException e) {
    18. e.printStackTrace();
    19. }
    20. }
    21. }
    22. }

    }

  • 多线程数据共享问题

多个线程共享数据时,可能会引发数据的不安全问题。

  1. package Threads;
  2. public class TicketThread implements Runnable {
  3. private int ticket = 10;//记录车票总数
  4. private int num = 0;//记录用户抢到了第几张票
  5. //用户抢票
  6. @Override
  7. public void run() {
  8. while (true) {
  9. if (ticket <= 0) {
  10. break;
  11. }
  12. //有余票,则抢票
  13. //修改车票数:总票数在抢完票后减一张
  14. ticket--;
  15. //用户抢完票后,票数加一
  16. num++;
  17. //模拟网络延迟
  18. try {
  19. Thread.sleep(500);
  20. } catch (InterruptedException e) {
  21. e.printStackTrace();
  22. }
  23. //显示出票反馈给用户
  24. System.out.println(Thread.currentThread().getName() + "抢到了第" + num + "张票,剩余" + ticket + "张票");
  25. }
  26. }
  27. }
  28. package Test;
  29. import Threads.TicketThread;
  30. public class TicketThreadTest {
  31. public static void main(String[] args) {
  32. Runnable runnable = new TicketThread();
  33. Thread t1 = new Thread(runnable);
  34. Thread t2 = new Thread(runnable);
  35. Thread t3 = new Thread(runnable);
  36. System.out.println("各方开始抢票");
  37. t1.start();
  38. t2.start();
  39. t3.start();
  40. }
  41. }

java线程同步

发表评论

表情:
评论列表 (有 0 条评论,348人围观)

还没有评论,来说两句吧...

相关阅读