亲宝软件园·资讯

展开

Java Thread

/少司命 人气:0

一,Thread 的几个常见属性

Thread 类是 JVM 用来管理线程的一个类,换句话说,每个线程都有一个唯一的 Thread 对象与之关联。

Java中创建线程

显示继承Thread,重写run方法来指定线程执行的代码

匿名内部类来继承Thread,重写run方法来指定线程执行的代码

显示实现Runnable接口,重写run方法

匿名内部类来继承Runnable接口,重写run方法

通过lambda表达式来描述执行的代码

属性获取方法
IDgetId()
名称getNmame()
状态getState()
优先级getPriority()
是否后台线程isDaemon()
是否存活isAlive()
是否被中断isInterrupted()

ID 是线程的唯一标识,不同线程不会重复

名称是各种调试工具用到 状态表示线程当前所处的一个情况,下面我们会进一步说明

优先级高的线程理论上来说更容易被调度到

关于后台线程,需要记住一点:JVM会在一个进程的所有非后台线程结束后,才会结束运行。

是否存活,即简单的理解,为 run 方法是否运行结束了

线程的中断问题,下面我们进一步说明

public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread("123"){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++){
                    System.out.println(Thread.currentThread().getName());
                    try{
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("线程退出");
            }
        };
 
        //这一组属性,线程创建完成后,属性就不变了
        System.out.println(t.getName());
        System.out.println(t.getPriority());
        System.out.println(t.isDaemon());
        System.out.println(t.getId());
        //这组属性会随着线程的运行而开始改变
        System.out.println(t.isAlive());
        System.out.println(t.isInterrupted());
        System.out.println(t.getState());
 
        t.start();
 
        while (t.isAlive()){
            System.out.println("123 正在运行");
            System.out.println(t.getState());
            System.out.println(t.isInterrupted());
            Thread.sleep(300);
        }
    }

二,线程调试

1,启动一个线程

之前我们已经看到了如何通过覆写 run 方法创建一个线程对象,但线程对象被创建出来并不意味着线程就开始运行了。

覆写 run 方法是提供给线程要做的事情的指令清单

线程对象可以认为是把 李四、王五叫过来了

而调用 start() 方法,就是喊一声:”行动起来!“,线程才真正独立去执行了。

 static class MyThread extends Thread{
        @Override
        public void run() {
            System.out.println("我是一个线程");
        }
    }
 
    public static void main(String[] args) {
        Thread t = new MyThread();
        t.start();
    }

2,中断一个线程

中断让一个程序结束,结束可能有两种情况

        1,已经把任务执行完了

        2,任务执行到一半,被强制结束

public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(){
            @Override
            public void run() {
               while (! isQuit){
                   System.out.println("正在转账");
                   try {
                       Thread.sleep(500);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
                System.out.println("转账终止");
            }
        };
        t.start();
        Thread.sleep(500);
        System.out.println("有内鬼,终止交易");
        isQuit = true;
    
}

public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(){
            @Override
            public void run() {
                while (!Thread.interrupted()){
                    System.out.println("正在转账");
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        break;
                    }
                }
                System.out.println("转账终止");
            }
        };
        t.start();
        Thread.sleep(5000);
        System.out.println("有内鬼,终止交易");
        t.interrupt();
    }

thread 收到通知的方式有两种:

1. 如果线程因为调用 wait/join/sleep 等方法而阻塞挂起,则以 InterruptedException 异常的形式通 知,清除中断标志

        当出现 InterruptedException 的时候, 要不要结束线程取决于 catch 中代码的写法. 可以选择 忽略这个异常, 也可以跳出循环结束线程.

2.否则,只是内部的一个中断标志被设置,thread 可以通过

        Thread.interrupted() 判断当前线程的中断标志被设置,清除中断标志

        Thread.currentThread().isInterrupted() 判断指定线程的中断标志被设置,不清除中断标志

这种方式通知收到的更及时,即使线程正在 sleep 也可以马上收到。

public static void main(String[] args) {
        Thread t = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++){
                    System.out.println(Thread.interrupted());
                }
            }
        };
        t.start();
        t.interrupt();
    }

public static void main(String[] args) {
        Thread t = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++){
                    System.out.println(Thread.currentThread().isInterrupted());
                }
            }
        };
        t.start();
        t.interrupt();
    }

3,等待一个线程

t1与t2串行执行

 public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++){
                    System.out.println("我是线程1");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
 
 
        Thread t2 = new Thread(){
            @Override
            public void run() {
               for (int i = 0; i < 10; i++){
                   System.out.println("我是线程2");
                   try {
                       Thread.sleep(50);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
            }
        };
 
 
        t1.start();
        t1.join();
        t2.start();
        t2.join();
        System.out.println("主线程执行完毕");
    }

t1与t2并发执行

public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++){
                    System.out.println("我是线程1");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
 
 
        Thread t2 = new Thread(){
            @Override
            public void run() {
               for (int i = 0; i < 10; i++){
                   System.out.println("我是线程2");
                   try {
                       Thread.sleep(50);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
            }
        };
 
 
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("主线程执行完毕");
    }

4,休眠线程

public static void main(String[] args) throws InterruptedException {
        System.out.println(System.currentTimeMillis());
        Thread.sleep(1000);
        System.out.println(System.currentTimeMillis());
    }

1,如果线程在正常运行计算判断逻辑,此时就是在就绪队列中排队,调度器就会从就绪队列中筛选出合适的PCB让他在CPU上运行

2,如果某个线程调用sleep就会让对应的线程的PCB进入阻塞队列,阻塞队列无法在PCB上运行

3,时间到了之后,就自动把这个PCB拿回到原来的就绪队列中

加载全部内容

相关教程
猜你喜欢
用户评论