自学内容网 自学内容网

二、Thread常见的方法

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

2.1 Thread 的常⻅构造⽅法

方法说明
Thread()创建线程
Thread(Runnable target)使用 Runnable 实现多线程
Thread(String name)创建线程 并命名
Thread(Runnable target, String name)使用 Runnable 和自定义名称实现多线程
【了解】Thread(ThreadGroup group, Runnable target)线程可以属于一个线程组,这个组由 ThreadGroup 类来表示,该构造器允许我们将线程添加到指定的线程组中。

Thread t1 = new Thread();
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread("这是我的名字");
Thread t4 = new Thread(new MyRunnable(), "这是我的名字");

2.2 Thread 的⼏个常⻅属性

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

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

• 名称是各种调试⼯具⽤到

• 状态表⽰线程当前所处的⼀个情况,下⾯我们会进⼀步说明

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

• 关于后台线程,需要记住⼀点:JVM会在⼀个进程的所有⾮后台线程结束后,才会结束运⾏。

• 是否存活,即简单的理解,为 run ⽅法是否运⾏结束了

package Demo03;

public class ThreadDemo {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    System.out.println(Thread.currentThread().getName() + ": 我还没死");
                            Thread.sleep(1 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + ": 我即将死去");
        });
        
        
        System.out.println(Thread.currentThread().getName()
                + ": ID: " + thread.getId());
        System.out.println(Thread.currentThread().getName()
                + ": 名称: " + thread.getName());
        System.out.println(Thread.currentThread().getName()
                + ": 状态: " + thread.getState());
        System.out.println(Thread.currentThread().getName()
                + ": 优先级: " + thread.getPriority());
        System.out.println(Thread.currentThread().getName()
                + ": 后台线程: " + thread.isDaemon());
        System.out.println(Thread.currentThread().getName()
                + ": 活着: " + thread.isAlive());
        System.out.println(Thread.currentThread().getName()
                + ": 被中断: " + thread.isInterrupted());
     
        thread.start();
        while (thread.isAlive()) {}
        System.out.println(Thread.currentThread().getName()
                + ": 状态: " + thread.getState());
    }
}

2.3 启动⼀个线程 - start()

但线程对象被创建出来并不意味着线 程就开始运⾏了。

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

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

• ⽽调⽤ start() ⽅法,就是喊⼀声:”⾏动起来!“,线程才真正独⽴去执⾏

注意:

调⽤ start ⽅法, 才真的在操作系统的底层创建出⼀个线程.

package Demo03;

public class Test {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            System.out.println("Thread 1"); 
        });
        t.start();
    }
}

2.4 中断⼀个线程

停⽌线程的⽅式:

1. 通过共享的标记来进⾏沟通

2. 调⽤ interrupt() ⽅法来通知

⽰例-1: 使⽤⾃定义的变量来作为标志位.

package Demo03;

public class ThreadDemo {
    private static class MyRunnable implements Runnable {
        public volatile boolean isQuit = false;
        @Override
        public void run() {
            while (!isQuit) {
                System.out.println(Thread.currentThread().getName()
                        + ": 别管我,我忙着转账呢!");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()
                    + ": 啊!险些误了⼤事");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyRunnable target = new MyRunnable();
        Thread thread = new Thread(target, "李四");
        System.out.println(Thread.currentThread().getName() + ": 让李四开始转账。");

        thread.start();
        //主线程睡10秒
        Thread.sleep(10 * 1000);
        

        System.out.println(Thread.currentThread().getName() + ": ⽼板来电话了,得赶紧通知李四对⽅是个骗⼦!");
        target.isQuit = true;
    }
    }

⽰例-2: 使⽤ Thread.interrupted() 或者 Thread.currentThread().isInterrupted() 代替⾃定义标志位.

方法说明
public void interrupt()中断与对象关联的线程,如果线程正在阻塞(如等待锁或处于sleep()状态),则会抛出InterruptedException,并将线程的状态设置为“已中断”。
public static boolean interrupted()判断当前线程的中断标志位是否已经设置。如果设置了,则清除该标志位并返回true;否则返回false。注意,这个方法会清除中断状态,所以连续两次调用不会立即返回true。
public boolean isInterrupted()检查与对象关联的线程的中断标志位是否已经设置。它不会清除中断状态,所以即使在连续多次调用时也可以检测到中断状态。

使⽤ thread 对象的 interrupted() ⽅法通知线程结束.

package test;

public class ThreadDemo {
    private static class MyRunnable implements Runnable {
        @Override
        public void run() {
            // 两种⽅法均可以
            while (!Thread.interrupted()) {
                //while (!Thread.currentThread().isInterrupted()) {
                System.out.println(Thread.currentThread().getName()
                        + ": 别管我,我忙着转账呢!");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println(Thread.currentThread().getName()
                            + ": 有内⻤,终⽌交易!");
                    // 注意此处的 break
                    break;
                }
            }
            System.out.println(Thread.currentThread().getName()
                    + ": 啊!险些误了⼤事");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyRunnable target = new MyRunnable();
        Thread thread = new Thread(target, "李四");
        System.out.println(Thread.currentThread().getName()
                + ": 让李四开始转账。");
        thread.start();
        Thread.sleep(10 * 1000);
        System.out.println(Thread.currentThread().getName()
                + ": ⽼板来电话了,得赶紧通知李四对⽅是个骗⼦!");
        thread.interrupt();
    }
}

2.5 等待⼀个线程 - join()

有时,我们需要等待⼀个线程完成它的⼯作后,才能进⾏⾃⼰的下⼀步⼯作。例如,张三只有等李四 转账成功,才决定是否存钱,这时我们需要⼀个⽅法明确等待线程的结束。

package test;

public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        Runnable target = () -> {
            for (int i = 0; i < 10; i++) {
                try {
                    System.out.println(Thread.currentThread().getName()
                            + ": 我还在⼯作!");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + ": 我结束了!");

        };
        Thread thread1 = new Thread(target, "李四");
        Thread thread2 = new Thread(target, "王五");
        System.out.println("先让李四开始⼯作");
        thread1.start();
        thread1.join();
        System.out.println("李四⼯作结束了,让王五开始⼯作");
        thread2.start();
        thread2.join();
        System.out.println("王五⼯作结束了");
    }
}
方法说明
public void join()等待线程结束
public void join(long millis)筦待线程结束,最多等 millis 毫秒
public void join(long millis, int nanos)同理,但可以更高精度

2.6 获取当前线程引⽤

方法说明
public static Thread currentThread();返回当前线程对象的引用
public class ThreadDemo {
 public static void main(String[] args) {
 Thread thread = Thread.currentThread();
 System.out.println(thread.getName());
 }
}

2.7 休眠当前线程

方法说明
public static void sleep(long millis) throws InterruptedException使当前正在执行的线程休眠(暂停执行)指定的毫秒数
public static void sleep(long millis, int nanos) throws InterruptedException使当前正在执行的线程休眠(暂停执行)指定的毫秒数加上纳秒数
public class ThreadDemo {
 public static void main(String[] args) throws InterruptedException {
 System.out.println(System.currentTimeMillis());
 Thread.sleep(3 * 1000);
 System.out.println(System.currentTimeMillis());
 
}
}


原文地址:https://blog.csdn.net/m0_63272315/article/details/142952094

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!