线程基础属性

1. 线程中断

线程处于阻塞状态,即调用当前线程的interrupt中断方法,线程是会抛出中断异常的
那么可以用这种方式来介入到运行中的线程,比如发起中断请求,要求当前线程终止运行
因为Java在语言层面,已经彻底抛弃stop语句,即终止当前正在运行的线程的方法,所以你另辟蹊径

package com.yli.thread.demo;

/**
 * 线程中断测试:表明线程在阻塞状态期间(调用sleep或者wait方法)</br>
 * 如果中断线程,会抛出异常,其实这也是一种介入到运行中线程的设计方法...比如在某种情况下,需要发出指令,终止线程!
 */
public class InterruptTest {

    public static void main(String[] args) {
        // 启动工作线程
        Thread t = new Thread(new Job());
        t.start();

        try {
            System.out.println();
            System.err.println("---- 主线程休眠0.5秒,好让job线程确定进入sleep状态 ----");
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // false
        System.out.println("线程中断前的状态:" + t.isInterrupted());

        System.out.println("---- 调用job线程中断方法----");

        t.interrupt();

    }

    private static class Job implements Runnable {

        @Override
        public void run() {
            System.out.println("--- begin sleep ---");

            // 测试方法一:循环检测中断状态
            while(!Thread.currentThread().isInterrupted()) {
                System.out.println("-----------线程没有中断-----------");
            }
            System.out.println("线程中断后的状态:" + Thread.currentThread().isInterrupted());


            // 测试方法二:如果处于阻塞状态,调用interrupt方法就会抛出中断异常
            // 并且线程的中断状态被清除了:意味着你拿到的 isInterrupt()仍然是false,这里要特别注意!!!
//            try {
//                Thread.sleep(10000);
//            } catch (InterruptedException e) {
//                System.out.println("--- job线程收到了中断请求:不过你可以据此做出一些操作 ---");
//                
//                // false:为什么线程被中断后,还是false状态,因为中断异常后,中断状态被清除
//                System.out.println("线程中断后的状态:" + Thread.currentThread().isInterrupted());
//                e.printStackTrace();
//            }
            System.out.println("--- end sleep ---");
        }
    }
}
2. 线程阻塞与等待

实际上这两个状态是有很大区别的,分别来介绍
(1)阻塞状态
比如线程A和线程B同时持有共享对象obj,线程A已经进入了对象obj的synchronize同步方法,即线程A已经获得了锁
此时线程B也要调用obj的同步方法,由于线程A已经占有了锁,那么线程B在获取这个锁的过程中,处于阻塞状态

(2)等待状态
假设线程A已经获得锁,在运行过程中,发现一些条件不满足(比如转账发现余额不足),那么必须等待余额足够才能继续运行下去。线程A调用对象的wait(3000)方法,即等待3秒钟,看这段时间内是否有资金打入这账户,一旦余额足够,线程A就有机会被唤醒,再次获得锁,就能执行转账操作了。那么从调用wait方法直到线程被唤醒的这个过程中,线程处于等待状态。

特别提醒:很多人还会问到sleep和wait的区别,其实wait明显是会释放锁,而sleep虽然也是进入等待状态,但不会释放锁。这就是最大的区别!!!

简单来概括:阻塞是线程尝试 获得锁 的过程,等待是线程 放弃锁 之后直到被唤醒的过程

3. 线程异常处理器

通常我们catch住异常,并没有做什么特殊处理,或者这种方式也并不那么优雅
可以实现 Thread.UncaughtExceptionHandler 接口,定义自己的异常后处理器

package com.yli.thread.demo;

import java.lang.Thread.UncaughtExceptionHandler;

public class ExceptionTest {

    public static void main(String[] args) {
        // 启动工作线程
        Thread t = new Thread(new Job());

        // 启动线程之前设置你的异常后置处理器
        t.setUncaughtExceptionHandler(new JobException());

        t.start();
    }

    private static class Job implements Runnable {

        @Override
        public void run() {
            System.out.println("--- begin sleep ---");

            System.out.println(10 / 0);

            System.out.println("--- end sleep ---");
        }
    }

    private static class JobException implements UncaughtExceptionHandler {

        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.out.println("----捕获到了线程运行时的异常----");
            System.out.println("----线程:" + t.getName() + ",异常堆栈信息如下----");
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值