多种方式控制线程执行顺序

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

最近遇到一个有点意思的题目,要控制两句数据的顺序,其实就是控制主线程和子线程的执行顺序。

原代码如下

public class TestAB {
    public static void A() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("2   " + System.currentTimeMillis());
            }
        }).start();
        System.out.println("1   " + System.currentTimeMillis());
    }

    public static void main (String[] args) {
        A();
    }

}

正常情况下都会先输出1  再输出2

但是要求先输出2 再输出1 ,可以用线程通信来尝试解决。

可以用 锁、volatile、wait、join、interrupted 这五种方式

1、volatile

volatile的介绍之前有写过  volatile 介绍 

修改后的代码如下,先创建一个volatile 的boolean值,初始值为false,在输出2之后再修改为true

do while 循环体只做循环其他的不执行,直到 isRun 被修改为true,再执行 if 语句。这是一种方式。

public class TestAB {
    public volatile static boolean isRun = false;
    public static void A() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("2   " + System.currentTimeMillis());
                isRun = true;
            }
        }).start();
        do {} while (!isRun);
        if(isRun) {
            System.out.println("1   " + System.currentTimeMillis());
        }
    }

    public static void main (String[] args) {
        A();
    }
}

2、join 

修改后代码如下,主线程调用子线程的 join 方法,主线程等子线程执行完再继续执行,此时也能实现先输出2再输出1

public class TestJoin {
    public static void A() {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("2   " + System.currentTimeMillis());
            }
        });
        t1.start();
        try {
            t1.join();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("1   " + System.currentTimeMillis());
    }

    public static void main (String[] args) {
        A();
    }
}

3、interrupted 

修改后如下,原理与第一种方式相似,等输出2后再修改标志位,还没调用interrupted时,isInterrupted 返回false,调用后就会返回true,也可以做到控制主线程和子线程的执行顺序。

interrupted 介绍

public class TestInterrupted {
    public static void A() {
        final Thread main = Thread.currentThread();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("2   " + System.currentTimeMillis());
                main.interrupt();
            }
        }).start();
        do { } while(!main.isInterrupted());
        if(main.isInterrupted()) {
            System.out.println("1   " + System.currentTimeMillis());
        }
    }

    public static void main (String[] args) {
        A();
    }
}

 wait 和 锁的也类似,使用wait也得加锁。

 

“把start改成run也可以~  那就不是多线程了哈哈~  只是执行一个run方法,主线程按顺序执行”

 

 

转载于:https://my.oschina.net/xiaozhiwen/blog/3018363

你可能感兴趣的:(多种方式控制线程执行顺序)