run()方法(只是一个内部方法)

run()方法只是一个类中的普通方法,调用run方法跟调用普通方法一样。
方法 run()称为线程体,它包含了要执行的这个线程的内容,线程就进入了 【运行状态】,开始运行 run 函数当中的代码。
Run 方法运行结束, 此线程终止。再调用start方法报错的。
然后 CPU 再调度其它线程。

启动线程start()方法(开启一个线程)

在 Java中启动多线程调用的是start方法。
在start方法中,真正实现多线程的是一个本地的方法start0。
调用start方法启动一个线程,此时的状态是 就绪。
无需等待run方法体代码执行完毕,可以继续执行下面的代码。

public  class TestDemo {
    public static void main(String[] args) {

        Runnable test = new  Runnable() {
            public void run() {
                String name = Thread.currentThread().getName();
                System.out.println("当前运行的线程 : " + name);
            }
        };

        test.run();

        // 开启多线程,执行run方法
        new Thread(test).start();
    }
}

Java run的作用 java run()方法_ide

等待一个线程-join()

join()方法是Thread类中的一个方法,该方法的定义是等待该线程终止。其实就是join()方法将挂起调用线程的执行,直到被调用的对象完成它的执行。

现在有两个线程t1和t2,那么如何让t1执行完毕,再去执行t2呢,这里我们就可以用到join()方法,
等待t1执行完毕,再去执行t2线程!!

public  class TestDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    try {
                        System.out.println(this.getName()+"还在运行!");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(this.getName()+"结束了!");
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    try {
                        t1.join();
                        System.out.println(this.getName()+"还在运行!");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(this.getName()+"结束了!");
            }
        };
        t1.start();
        t2.start();
    }
}

Java run的作用 java run()方法_Java run的作用_02


如果我们,不等待t1线程结束,那么t1线程和t2线程谁会先执行,完全取决于操作系统的调度。也就是并发执行。

public  class TestDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    try {
                        System.out.println(this.getName()+"还在运行!");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(this.getName()+"结束了!");
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    try {
                        //t1.join();
                        System.out.println(this.getName()+"还在运行!");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(this.getName()+"结束了!");
            }
        };
        t1.start();
        t2.start();
    }
}

Java run的作用 java run()方法_java_03


同时join()里也可以设定等待时间,等到这个时间后,就不在等了。

public  class TestDemo {
    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(this.getName()+"在运行");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread t2 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {

                    System.out.println(this.getName()+"在运行");
                    try {

                        Thread.sleep(1000);

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        t1.start();
        t1.join(7000);
        System.out.println("我不等了");
        t2.start();
    }
}

Java run的作用 java run()方法_多线程_04

中断一个线程,调用 interrupt() 方法来通知

在t1线程运行1m后中断线程。
Thread.currentThread().isInterrupted()内置的一个标记位不用用户自己来创建代码判定。
调用interrupt方法来进行中断时,会遇到2种情况。
a)情况1:如果当线程内部执行的逻辑不涉及到sleep这样的等待,此时就会通过这个标记位来进行退出。

public  class TestDemo {
    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(){
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()){
                    System.out.println(Thread.currentThread().getName()+" 在运行");
                }
            }
        };

        t1.start();
        Thread.sleep(1000);
        t1.interrupt();
    }
}

Java run的作用 java run()方法_java_05


b)情况2:如果当前线程内部执行的逻辑已经进入sleep了,此时就会触发一个InterruptedException,通过catch捕获到异常,在继续决定如何处理。

这里不做处理,线程就会继续循环才去。

public  class TestDemo {
    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(){
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+" 在运行");
                }
            }
        };

        t1.start();
        Thread.sleep(5000);
        t1.interrupt();
    }
}

Java run的作用 java run()方法_java_06


此时这里里的break,本质上是让线程的方法能够执行结束~

但是线程是否要结束,还是根据线程自身的方法来决定的~

public  class TestDemo {
    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(){
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    	//e.printStackTrace();自己打印异常信息
                        break;
                    }
                    System.out.println(Thread.currentThread().getName()+" 在运行");
                }
            }
        };

        t1.start();
        Thread.sleep(5000);
        t1.interrupt();
    }
}

Java run的作用 java run()方法_Java run的作用_07

currentThread()方法获取当前线程对象的引用

在那个线程中调用,就获取到那个线程对象的引用
如果线程是通过创建Thread子类,并重写run方法来创建的话,此时run方法中,也可以使用this,也能直接找到该线程的引用。
如果是通过Runnable 或者别的方法创建的话,不能用this,只能用Thread.currentThread()。

public  class TestDemo {
    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(){
            @Override
            public void run() {
                System.out.println(this.getId());
            }
        };

        Thread t2 = new Thread(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getId());
            }
        };

        t1.start();

        t2.start();
        System.out.println(Thread.currentThread().getId());
    }
}

Java run的作用 java run()方法_ide_08

sleep() 休眠线程

在前几篇博客也使用到了,以及上面的代码也使用到了,他是干什么的呢?
也就是休眠当前线程多少ms后在继续执行线程,但是要抛出 InterruptedException异常。
当前线程进入“休眠状态”即从“运行态”变为“阻塞态”。
在线程休眠结束时,会重新变为“就绪态”等待CPU的调度。

进入休眠状态后,会进入到cpu的等待队列中,直到休眠时间到达,再放回就绪队列,放回就绪队列后,至于啥时候去CPU上运行,就要看调度器是否会立马调度。