JAVA | 线程(三)控制线程

一、Join线程

当前线程调用了 另一个线程的join() 方法,当前线程会阻塞,直到 被join的线程执行完成后 才会继续执行。

public class JoinThread extends Thread{
        JoinThread(String name){
            super(name);
        }

        @Override
        public void run() {
            super.run();
            for (int i=0;i<100;i++){
                Log.e("testthread",getName() +","+ i);
            }
        }
    }

mBntFun4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new JoinThread("新线程").start();
                for (int i = 0;i<100;i++){
                    Log.e("testthread",Thread.currentThread().getName() +","+ i);
                    if (i == 20){
                        // 启动新线程
                        JoinThread joinThread = new JoinThread("join线程");
                        joinThread.start();
                        try {
                            //1. 调用新线程的join方法,当前线程会阻塞,知道join的线程执行完成
                            joinThread.join();

                            // 2.当前线程最多等待1毫秒,超过20毫秒Join的线程还没有执行完,则不再等待
                            //joinThread.join(1);
                            
                            //3. 当前线程最多等待1毫秒加10毫微秒(一般不用这个,因为程序无法精确到毫微秒)
                            //joinThread.join(1,10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });

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

说明
join方法有以上代码的三种重载方式

二、后台线程(守护线程、精灵线程)

  1. 有些线程在后台运行,为其他线程提供服务,比如JVM垃圾回收线程
  2. 当所有的前台线程死亡,那后台线程也会随之死亡,因为当前台进程都死亡后,就没有运行的必要了,虚拟机也就退出了,后台进程也就死亡了。
  3. 主线程默认是前台线程,前台线程创建的子线程是前台线程,后台线程创建的子线程是后台线程
  4. 调用线程的 setDaemon(true) 设置为后台线程
  5. 调用线程 isDaemon() 判断是否是后台线程
  6. setDaemon要在start()之前调用
class FirstThread extends Thread{
        private int i;
        @Override
        public void run() {
            super.run();
            for (;i < 1000; i++){
                Log.e("testthread",getName() +","+ i);
            }
        }
    }
 mBntFun5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FirstThread thread = new FirstThread();
                // 要在start()之前调用
                thread.setDaemon(true);
                //启动线程
                thread.start();
                
                for (int i=0;i<10;i++){
                    Log.e("testthread",Thread.currentThread().getName() +","+ i);

                }
                // 主线程运行到这就结束了,后台线程也随之结束,所以thread并不会打印到 999
            }
        });

三、线程睡眠 :sleep(是Thread的静态方法)

可以让正在执行的线程暂停一段时间,进入阻塞状态

mBntFun5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                for (int i=0;i<10;i++){
                    Log.e("testthread",Thread.currentThread().getName() +","+ new Date());
                    try {
                        //让主线程睡1毫秒
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

在这里插入图片描述说明
从上面的运行结果可以看到,线程每隔一秒打印一次

  1. sleep也有两种重载方式:
  • void sleep(long millis) : 暂停多少毫秒
  • void sleep(long millis, int nanos):暂停多少毫秒加毫微秒(一般不用这个)
  1. 线程调用sleep()进入阻塞后,在睡眠时间内,不会获得执行的机会即便系统中没有其他线程在执行,处于sleep状态的线程也不会执行

四、线程让步 :yield(静态方法)

可以暂停当前的线程,让它进入就绪状态,并不会阻塞该线程

class FirstThread extends Thread{
        FirstThread(String name){
            super(name);
        }

        @Override
        public void run() {
            super.run();
            for (int i=0;i < 100; i++){
                Log.e("testthread",getName() +","+ i);
                if (i == 20){
                    Thread.yield();
                }
            }
        }
    }

mBntFun5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FirstThread thread1 = new FirstThread("高级");
                thread1.setPriority(Thread.MAX_PRIORITY);
                thread1.start();

                FirstThread thread2 = new FirstThread("低级");
                 thread2.setPriority(Thread.MAX_PRIORITY);
                thread2.start();
            }
        });

未设置优先级设置了优先级说明

  1. 通过**setPriority()**设置线程的优先级
  2. 调用yield()后,只有和当前线程同级或者比他优先级高的才会获得执行的机会
  3. 没有比它优先级高的线程,调用yield()后当前线程继续执行
sleep()和yield()的区别:
  1. 优先级:sleep()调用后,不会理会其他线程的优先级;yield需要
  2. 状态:调用sleep()后会进入阻塞状态,经过阻塞事件才会进入就绪状态;而yield直接就进入就绪状态了
  3. 异常:调用sleep后会抛出InterruptedException异常,而yield没有抛出任何异常
  4. 可移植性:sleep()有更好的可移植性,**不建议用yield()来控制并发线程

五、改变线程的优先级

  1. 每个线程的优先级都和创建它的父线程优先级相同
  2. main线程具有普通优先级
  3. 设置优先级:
    setPriority(1~10)
    public static final int MAX_PRIORITY = 10;
    public static final int MIN_PRIORITY = 1;
    public static final int NORM_PRIORITY = 5;
  1. 返回优先级:
    getPriority()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值