学习线程优先级,线程礼让,线程死锁

144 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1.写 5 个线程,优先级分别设置成 2,4,6,8,10 线程名中有优先级 线程循环输出线程名及序号,每次中间休眠 5ms

实现代码:

 package com.zhangyufan.thread;
 ​
 public class TestThreadPriority {
 ​
     public static void main(String[] args) {
         ThreadPriority tp = new ThreadPriority();
         Thread t1 = new Thread(tp, "优先级:2");
         Thread t2 = new Thread(tp, "优先级:4");
         Thread t3 = new Thread(tp, "优先级:6");
         Thread t4 = new Thread(tp, "优先级:8");
         Thread t5 = new Thread(tp, "优先级:10");
         t1.setPriority(2);
         t2.setPriority(4);
         t3.setPriority(6);
         t4.setPriority(8);
         t5.setPriority(10);
         t1.start();
         t2.start();
         t3.start();
         t4.start();
         t5.start();
     }
 ​
 }
 ​
 class ThreadPriority implements Runnable {
 ​
     @Override
     public void run() {
         for (int i = 0; i < 5; i++) {
             System.out.println(Thread.currentThread().getName() + "---" + i);
             try {
                 Thread.sleep(5);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
     }
 ​
 }

运行结果:

在这里插入图片描述

2.写 1 个线程,对比使用礼让和不使用礼让所使用的时间。

为了观察到时间上的差别,这里将循环次数设置成了5000(也可以稍微小一点点或者更大),并且在run()方法的开始和结束是使用Date类中的getTime()方法并计算了所用时间,以此对比时间的差别。

更新于2021.10.1晚7点: 有小伙伴私信我说这个礼让在运行的时候发现有时候会出现礼让比不礼让用时短的情况,我上网查了点资料发现,yield()方法只是给当前正在处于运行状态下的线程一个提醒,告知它可以将资源礼让给其它线程,但这仅仅是一种暗示,没有任何一种机制保证当前线程会将资源礼让,通俗的来说,用了yield()方法,它并不一定真的会礼让,这也就解释了运行多次会出现的礼让的时长比不礼让的时长还要短的情况。

实现代码:

 package com.zhangyufan.thread;
 ​
 public class TestThreadYield {
 ​
     public static void main(String[] args) throws InterruptedException {
         ThreadYield thread = new ThreadYield();
         Thread t1 = new Thread(thread, "线程1");
         t1.start();
     }
 ​
 }
 ​
 class ThreadYield implements Runnable {
 ​
     @Override
     public void run() {
         long t1 = new java.util.Date().getTime();
         System.out.println(Thread.currentThread().getName() + "开始时间:" + t1);
         for (int i = 0; i < 5000; i++) {
             System.out.println(Thread.currentThread().getName() + "---" + i);
             /*if (i == 3) {
                 System.out.println(Thread.currentThread().getName() + "礼让");
                 Thread.currentThread().yield();
             }*/
             if (i == 3) {
                 System.out.println(Thread.currentThread().getName() + "礼让");
                 Thread.currentThread().yield();
             }
         }
         long t2 = new java.util.Date().getTime();
         System.out.println(Thread.currentThread().getName() + "结束时间:" + t2);
         System.out.println(Thread.currentThread().getName() + "所用时长:" + (t2 - t1) + "ms");
     }
 ​
 }

运行结果:

第一二张图是使用礼让的,第三四张图是不用礼让的,省去中间循环输出的内容。可以发现,其实没什么差别,几毫秒而已。

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

  1. 写 2 个人吃饭,只有一双筷子和一只碗,其中 1 人拿着筷子,另一个人拿着碗。2 人都想从对方手中拿到需要的东西,而自己只有吃完饭才会放弃手中的东西,只有当一个人同时有筷子和碗时才能吃饭。用线程编写上面的情况,表现出 2 个人都吃不上饭的情况。

实现代码:

 package com.zhangyufan.thread;
 ​
 public class TestThreadLock {
 ​
     public static void main(String[] args) throws InterruptedException {
         ThreadLock tl = new ThreadLock();
         tl.name = "张三";
         new Thread(tl).start();
         Thread.sleep(100);
         tl.name = "李四";
         new Thread(tl).start();
     }
 ​
 }
 ​
 class ThreadLock implements Runnable {
     Object chopsticks = new Object();
     Object bowl = new Object();
     String name;
 ​
     @Override
     public void run() {
         if ("张三".equals(name)) {
             synchronized (chopsticks) {
                 System.out.println("张三拿到筷子了,去拿碗");
                 try {
                     Thread.sleep(300);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
                 synchronized (bowl) {
                     System.out.println("张三拿到筷子和碗了,可以吃饭了");
                 }
             }
         } else if ("李四".equals(name)) {
             synchronized (bowl) {
                 System.out.println("李四拿到碗了,去拿筷子");
                 try {
                     Thread.sleep(300);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
                 synchronized (chopsticks) {
                     System.out.println("李四拿到筷子和碗了,可以吃饭了");
                 }
             }
         }
     }
 ​
 }

运行结果:

在这里插入图片描述