• java 多线程 3 : 控制线程


    join线程:    

    public class JoinThread extends Thread{
    
        public JoinThread(String name) {
            super(name);
        }
        public void run() {
            for(int i = 0 ; i < 100 ; i++) {
                System.out.println(getName() + " " + i);
            }
        }
        public static void main(String[] args) throws InterruptedException {
            new JoinThread("Thread-0:").start();
            for(int i = 0 ; i < 100 ; i++) {
                if(i == 20) {
                    JoinThread jt = new JoinThread("Join-Thread:");
                    jt.start();
                    jt.join();
                }
                System.out.println(Thread.currentThread().getName() + " " + i);
            }
        }
    }

      程序中有三个线程,Thread-0开始和main线程并发执行,当主程序i==20时,启动了名为Join-Thread线程,Join-Thread线程执行后和Thread-0并发执行 ,该线程不会和main线程并发执行,mian线程需要等待Join-Thread线程执行完毕之后再开始向下执行。

      当某个程序流中调用其他线程的join方法时,那么调用线程将会被阻塞,直到join方法加入的线程执行完成。

    join方法的重载:
      join():  等待被join的线程执行完成
      join(long millions):  等待被join的线程执行millions毫秒,如果再millios毫秒内还没执行完,就不再等待了
      join(long millions , int nanos)  等待被join线程最长millions加nanos毫微妙  

    后台线程:(守护线程 , 精灵线程)

      特征:所有的前台线程都死亡,后台线程会自动死亡。
      调用setDaemon(true) 将指定线程设置成为后台线程,需要在start()之前调用,否则引发IllegalThreadStateExcepiton异常

    public class DaemonThread extends Thread {
    
        public void run() {
            for(int i = 0 ; i < 1000 ; i++) {
                System.out.println(getName() + " " + i);
            }
        }
        public static void main(String[] args) {
            DaemonThread dt = new DaemonThread();
            dt.setDaemon(true);//设置成为后台线程
            dt.start();
            
            for(int i = 0 ; i < 10 ; i ++) {
                System.out.println(Thread.currentThread().getName() + " "  + i);
            }
            
            //-- main 线程结束后 , 后台线程也随之结束
        }
    }

    结果:后台线程可能在main线程结束的时候 并发执行一点,就结束了。

    线程睡眠:sleep

      如果需要让正在执行的线程暂停一段时间,可以通过Thread类的静态方法sleep()方法来实现
      static void sleep(long millis):  让当前正在执行的线程暂停millis毫秒 , 并且进入阻塞状态
      static void sleep(long millis , int nanos) 让当前正在执行的线程暂停millis毫秒 加nanos微妙 , 并且进入阻塞状态

    public class Thread5 extends Thread{
        public void run() {
            for(int i = 0 ; i < 30 ; i++) {
                System.out.println(getName() + " " + i);
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        public static void main(String[] args) {
            Thread5 t = new Thread5();
            Thread5 t2 = new Thread5();
            t.start();
            t2.start();
        }
    }

    线程让步:yield

       yield()和sleep()方法相似,可以让当前正在执行的线程暂停,但是不会阻塞该线程,它是让该线程转入就绪状态

    public class YieldThread extends Thread{
        public YieldThread(String name) {
            super(name);
        }
        public void run() {
            for(int i = 0 ; i < 50 ; i++) {
                System.out.println(getName() + " 优先级:" + getPriority() + "变量:" + i);
                if(i == 20) {
    //                Thread.yield();
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        public static void main(String[] args) {
            YieldThread y1 = new YieldThread("thread-0");
            YieldThread y2 = new YieldThread("xxxxxx");
            y1.start();
            y2.start();
            y1.setPriority(MAX_PRIORITY);
            y2.setPriority(MIN_PRIORITY);
        }
    }

    被yield方法暂停后,线程执行会受到优先级影响。

    改变线程优先级:

      每个线程执行时具有一定的优先级,优先级高的线程获得较多的执行机会,优先级较低的线程获得较少的机会。
      每个线程默认的优先级与创建它的父线程的优先级相同,默认情况下,main具有普通优先级,main创建的子线程也具有普通优先级
      Thread类提供setPriority(int newPriority) ,getPriority()方法来设置和返回指定线程的优先级 newPriority的值是整数,1-10之间,也可以使用静态常量
      MAX_PRIORITY: 10  MIN_PRIORITY:1  NORM_PRIORITY:5

    public class PriorityThread extends Thread{
    
        public PriorityThread(String name) {
            super(name);
        }
        
        public void run() {
            for(int i = 0 ; i < 50 ; i++) {
                System.out.println(getName() + " " + "优先级:" + getPriority() + "变量: " + i);
            }
        }
        
        public static void main(String[] args) {
            Thread.currentThread().setPriority(6);
            for(int i = 0; i < 30 ; i++) {
                if(i == 10) {
                    PriorityThread p1 = new PriorityThread("低级");
                    p1.start();
                    p1.setPriority(MIN_PRIORITY);
                }
                if(i == 20) {
                    PriorityThread p2 = new PriorityThread("高级");
                    p2.start();
                    p2.setPriority(MAX_PRIORITY);
                }
            }
        }
    }
    温故而知新
  • 相关阅读:
    分组PARTITION BY及游标CURSOR的用法
    dotnet core 3.1+consul 学习(1)
    常用状态码
    docker 安装consul以及部署consul集群
    泛型
    redis面试题(1)
    asp net core 3.1启动过程源码解读
    .net core 2.x到3.x变化 -> Endpoint Routing
    jwt登录验证逻辑
    .Net Core3.1+Jenkins+Docker+Git实现自动化部署
  • 原文地址:https://www.cnblogs.com/Uzai/p/9667907.html
Copyright © 2020-2023  润新知