二.线程常见的方法

    xiaoxiao2021-03-25  74

    一.线程的调度

    1、调整线程优先级:Java线程有优先级,优先级高的线程会获得较多的运行机会。   Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量: static int MAX_PRIORITY           线程可以具有的最高优先级,取值为10。 static int MIN_PRIORITY           线程可以具有的最低优先级,取值为1。 static int NORM_PRIORITY           分配给线程的默认优先级,取值为5。   Thread类的setPriority()和getPriority()方法分别用来设置和获取线程的优先级。   每个线程都有默认的优先级。主线程的默认优先级为Thread.NORM_PRIORITY。 线程的优先级有继承关系,比如A线程中创建了B线程,那么B将和A具有相同的优先级。 JVM提供了10个线程优先级,但与常见的操作系统都不能很好的映射。如果希望程序能移植到各个操作系统中,应该仅仅使用Thread类有以下三个静态常量作为优先级,这样能保证同样的优先级采用了同样的调度方式。

    二.上篇文章提到线程有五个状态,其中有一个阻塞状态,到底哪几种情况会导致线程阻塞呢?

    先看一下这个图:

    考虑一下三个方面,不考虑IO阻塞的情况:

    睡眠;

    等待;

    因为需要一个对象的锁定而被阻塞。

    这就涉及到线程常用的几个方法

    1.睡眠(线程的静态方法)

    Thread.sleep(long millis)Thread.sleep(long millis, int nanos)静态方法强制当前正在执行的线程休眠(暂停执行),使线程转到阻塞状态。millis参数设定睡眠的时间,以毫秒为单位。当睡眠结束后,就转为就绪(Runnable)状态。sleep()平台移植性好。

    睡眠的位置:放在run()方法之内。

    public class ThreadSleep implements Runnable{ @Override public void run() { for (int i = 1; i <= 100; i++) { System.out.println(i); try { //睡眠一秒 Thread.sleep(1000);//参数以毫秒计算 } catch (InterruptedException e) { e.printStackTrace(); } //每隔10个输出一个字符串 if(i==0){ System.out.println("-------"+i); } } } public static void main(String[] args) { ThreadSleep ts=new ThreadSleep(); Thread thread=new Thread(ts); thread.start(); } } 输出结果:(省略一部分)

    2、等待:

    Object类中的wait()方法,导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 唤醒方法,行为等价于调用 wait(0) 一样。 调用wait()notify()系列方法时,当前线程必须拥有此对象监视器(即对象锁)。  synchronized (obj) {     while (<condition does not hold>)     obj.wait();     ... // Perform action appropriate to condition          }     此方法只应由作为此对象监视器的所有者的线程来调用。

    3.让步(线程的静态方法)

    Thread.yield() 方法,暂停当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程。 public class ThreadYield extends Thread{ public ThreadYield(String name) { super(name); } @SuppressWarnings("static-access") @Override public void run() { for (int i = 0; i < 15; i++) { System.out.println(this.getName()+"------"+i); //当i为10时,线程就会把cpu时间让掉,让其他或者自己的线程执行 if(i==10){ this.yield(); } } } public static void main(String[] args) { ThreadYield ty1=new ThreadYield("小明"); ThreadYield ty2=new ThreadYield("小红"); ty1.start(); ty2.start(); } } 运行一下: 再次运行一下: 可以看出来:(实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。)

    4、加入(线程的非静态方法)

    join()方法,等待其他线程终止。在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态。 public class ThreadJoin implements Runnable{          private static int count=5;     public static int getCount() {         return count;     }     public static void setCount(int count) {         ThreadJoin.count = count;     }     @Override     public void run() {         for (int i = 0; i < 5; i++) {             count++;         }                  }     public static void main(String[] args) {         ThreadJoin join1=new ThreadJoin();         Thread t1=new Thread(join1);         t1.start();         System.out.println(count);              } } 运行一下: 为什么结果没有变呢?这是因为main方法本身也是一个线程,当主线程main方法执行完毕时,线程t1有可能正在启动,或者还没能运行完,总之就是晚于主线程的执行。 这时候join()方法就可以控制运行的顺序。 public static void main(String[] args) { ThreadJoin join1=new ThreadJoin(); Thread t1=new Thread(join1); t1.start(); try { t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(count); } 这时候结果就是10了。

     

    转载请注明原文地址: https://ju.6miu.com/read-35637.html

    最新回复(0)