Java多线程:控制线程的具体操作

1.创建线程 :start方法,在操作系统内部创建出一个新的线程

start和run之间的区别

调用 start 方法,才真的在操作系统的底层创建出一个线程

run方法只是描述了线程要执行的任务,只是一个普通方法

run方法应该由start内部来调用的,多线程编程应该用start方法

在Thread中的子类中重写run方法,就会被start里面创建的新线程来执行

start内部调用操作系统提供的api,创建线程。

然后让线程执行run方法中的代码

2.中断线程:让线程结束

让run方法执行完,线程就结束了

while (true) {//这种无限循环的情况,线程结束不了
            System.out.println("dxc1");//当然强制终止线程,线程也没了,这是特殊手段
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

1)手动设置一个标志位,来作为循环的判定条件

while (!isQuit) {//通过自己设定的变量,来控制循环是否结束,从而影响到线程是否结束
            System.out.println("dxc1");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
//这里的isQuit这个变量相当于在线程中读取。在main中修改
//当然如果这样来进行,其实也存在一定的缺陷

2)直接借助Thread实例中自己提供的一个标志位

我们虽然不能直接引用到这个标志位变量,咱们可以通过一些方法来操作标志位

Thread t = new Thread() {
            @Override
            public void run() {
                while (!this.isInterrupted()) {
                    System.out.println("hello thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        // 做一些其他工作~~
                        break;
                    }
                }
            }

在t的线程代码中,存在两种情况

  1. 执行打印和while循环判定(线程处于就绪状态
  2. 进行sleep(线程处于阻塞/休眠状态

调用interrupt方法时

  1. 如果线程处于就绪状态,此时是直接修改线程中对应的标志位
  2. 如果线程处于阻塞状态,此时会引起InterruptedException

interrupt方法这个方法,说是中断线程,但是不是直接立即马上的杀死线程

具体线程怎么退出,这是线程代码自己说了算

3.等待线程join

join可以控制线程结束的先后顺序

  1. 一旦执行到join当前调用join的线程main就会阻塞等待
  2. join的阻塞等待,于sleep的效果是一样的

join会进行等待,直到t线程执行完(t的run方法结束了

public class Demo12 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {//
            for (int i = 0; i < 5; i++) {//打印5次hello thread
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();

        System.out.println("t 线程尚未结束. ");
        // 主线程中, 可以使用 join 来进行等待.
        try {
            t.join();//当线程t在运行的时候,进行阻塞等待,一直到线程t的run方法执行完毕
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("t 线程已经结束. ");
    }
}

Java多线程:控制线程的具体操作_第1张图片

4.获取当前线程Thread对象的引用

拿到这个引用,才能做出一些后续操作,很多和线程相关的操作,都是依赖这样的引用

1)如果通过继承Thread来创建的线程。此时直接run方法中通过this,就能拿到这个线程的实例

Thread t = new Thread() {
            @Override
            public void run() {
                while (!this.isInterrupted()) {
                    System.out.println("hello thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        //做一些其它工作
                        break;
                    }
                }
            }
        };
        t.start();

2)更常见的是使用Thread里面的一个静态方法,currentThread(),哪个线程调用这个静态方法,就能够返回哪个线程的Thread实例引用,这种获取方式,可以在任何代码中使用。

代码1:
Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (this.isInterrupted()) {
                    
                }
            }
        });

在这个代码中,通过Thread.isInterrupted方法是不能直接调用的。

仔细一看,当前run不是Thread的方法,而是Runnable的方法

因此,this也就是指向的是Runnable

当然没有Thread类的属性和方法

代码2:
Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()) {
                    
                }
            }
        });

此时run虽然仍是Runnable的方法

但是是通过这个Thread的currentThread来获取到线程实例的

Thread.currentThread()这个方法是那个线程调用,就返回那个线程的实例

5.线程的休眠sleep

调用sleep的线程就会阻塞等待

取决于sleep中指定的时间

你可能感兴趣的:(Java学习,java,多线程)