Thread类中的join方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行。
当join的线程跑完,再并行执行其他线程。
class MyRunable implements Runnable{ @Override public void run() { for (int i = 0; i < 20; i++) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } } } }
public class ThreadDemo01 { public static void main(String[] args) { Thread thread = new Thread(new MyRunable()); thread.start(); for (int i = 0; i < 20; i++) { System.out.println(Thread.currentThread().getName() + " : " + i); if (i==12){ try { thread.join();// 当thread这个线程跑完,再跑其他线程。 } catch (InterruptedException e) { e.printStackTrace(); } } } } }
public static void main(String[] args) { Thread thread = new Thread(new MyRunable()); thread.start(); for (int i = 0; i < 20; i++) { System.out.println(Thread.currentThread().getName() + " : " + i); if (i==12){ thread.interrupt(); } } }
抛出异常,没能真的中断线程。说明 interrupt() 只是做了中断的标记。
java.lang.InterruptedException: sleep interrupted at java.base/java.lang.Thread.sleep(Native Method) at MyRunable.run(ThreadDemo01.java:38) at java.base/java.lang.Thread.run(Thread.java:834)
抛出 java.lang.InterruptedException 这个异常后, 中断标记被消除。
通过 判断 Thread.currentThread().isInterrupted() 来结束当前线程。
class MyRunable implements Runnable{ @Override public void run() { for (int i = 0; i < 20; i++) { // 判断 中断, 结束线程。 if(Thread.currentThread().isInterrupted()){ break; } System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); // 由于 java.lang.InterruptedException 异常,将中断消除了,所以再打一次中断标记。 Thread.currentThread().interrupt(); } } } }
class MyRunable2 implements Runnable{ boolean flag = true; public MyRunable2(){ this.flag = true; } @Override public void run() { int i = 0; while (flag){ System.out.println(Thread.currentThread().getName() + " : " + (i++)); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } } } }
改变 flag ,来中断线程。
public static void main(String[] args) { MyRunable2 myRunable = new MyRunable2(); Thread thread = new Thread(myRunable); thread.start(); for (int i = 0; i < 20; i++) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " : " + i); if (i==12){ myRunable.flag = false; } } }
小结
两种方法,相比较而言,使用 flag做标记更实用。因为方法 interrupt() 做的中断标记,容易被消除掉。
线程分为 守护线程 和 用户线程, 当用户线程 结束,JVM退出。
-
setDaemon(true);
-
Thread.yield();
让出cpu的资源,给其他线程运行。
thread.setPriority(Thread.MAX_PRIORITY);
优先级越高,抢占cpu资源的概率越大。