Thread练习题

2022-11-02 14:55:59 浏览数 (2)

  • 如果执行以下代码结果会输出什么,并说明思路
代码语言:javascript复制
    /*new 了一个对象(子对象)继承了Thread对象(父对象),在子对象里重写了父类的run()方法;然后父对象里面扔了个Runnable进去,父对象中的run()方法就是最初那个带有 if 判断的run()方法。现在执行start()后,肯定先在子类中找run()方法,找到了,父类的run()方法自然就被干掉了,所以会打印出:Thread run。*/
    //会优先执行子类重写的方法
    public static void main(String[] args) {
        new Thread(() -> System.out.println("runnable run")) {
            @Override
            public void run() {
                System.out.println("Thread run");
            }
        }.start();
    }
  • 写两个线程,一个线程打印1~52,另一个线程打印A~Z,打印顺序是12A34B...5152Z;

第一种方法:各个对象在线程体内,通过验证如果数值对象在循环到偶数时sleep一下等待字母输出,此方法需要设置线程优先值,一般数值大于字母两个优先值时比较稳定。

代码语言:javascript复制
//2、写两个线程,一个线程打印1~52,另一个线程打印A~Z,打印顺序是12A34B...5152Z;
    //    String[] str = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
    //    int[] num = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52}
public class ThreadDemo2 {

    public static void main(String[] args) {
        Thread t1 = new Thread(()->{
            int[] num = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52};
            for (int i = 0; i < num.length; i  ){
                // 要先输出再等待,如果先等待再输出可能会造成字母先于数字
                System.out.println(num[i]);
                if(num[i]%2 != 1){   //是偶数
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        t1.setPriority(3);// 设置线程优先级(重点)
        t1.start();
        // 不同的线程优先值结果不同,只要t1>t2两个优先值则受影响概率较小
        Thread t2 = new Thread(()->{
            String[] str = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
            for (int i = 0; i < str.length; i  ){
                // 要先输出再等待,如果先等待再输出可能会造成数字先于字母
                System.out.println(str[i]);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t2.setPriority(1);// 设置线程优先级(重点)
        t2.start();
    }
}

第二种方法:各个对象在线程体内,通过验证标志位来判断是否该自己输出,如果是数字执行两位也就是偶数的时候更改标志位让字母输出,字母输出完直接更改标志位,while循环的时候一定设置休眠,要不可能会卡死,这种方法比上面的方法稳定,通过标志位的判断输出保证了他们的输出顺序。

代码语言:javascript复制
//2、写两个线程,一个线程打印1~52,另一个线程打印A~Z,打印顺序是12A34B...5152Z;
    //    String[] str = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
    //    int[] num = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52}
public class ThreadDemo2 {

    private static boolean flag = true; // 定义一个标志位
    public static void main(String[] args) {

        new Thread(()->{
            int[] num = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52};
            for (int i = 0; i < num.length; i  ){
                // 如果flag是false就等待字母输出,while循环的时候定义一下休眠,不要让他一直去查这个值,要不它会卡掉
                while (flag == false){
                    try {
                        Thread.sleep(10);// 每次循环休眠0.01s
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(num[i]);// 输出值
                if(num[i]%2 != 1){   //是偶数,该字母输出了
                    flag = false;// 定义flag为false,告诉字母你该输出了
                }
            }
        }).start();

        new Thread(()->{
            String[] str = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
            for (int i = 0; i < str.length; i  ){
                // 如果flag是true就等待数字输出,while循环的时候定义一下休眠,不要让他一直去查这个值
                while (flag == true){
                    try {
                        Thread.sleep(10);// 每次循环休眠0.01s
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(str[i]);// 输出字母
                flag = true;// 因为字母每次输出一次所以输出完标志位直接定义为true
            }
        }).start();
    }
}
  • 子线程循环10次,主线程循环100次,然后子线程循环10次,主线程循环100次,这样循环50次;

由线程创建一个循环50次的for,在里面先创建子现场输出1-10,在子现场执行的时候为了保证输出顺序让主线程休眠0.01s以保证子线程输出完主线程才输出

代码语言:javascript复制
//3、子线程循环10次,主线程循环100次,然后子线程循环10次,主线程循环100次,这样循环50次;
class ThreadDemo3 {

    // 由线程创建一个循环50次的for,在里面先创建子现场输出1-10,在子现场执行的时候为了保证输出顺序让主线程休眠0.01s以保证子线程输出完主线程才输出
    public static void main(String[] args){
        for (int i = 0; i < 50; i  ) {
            new Thread(()->{
                for (int j = 0; j < 10; j  ) {
                    System.out.println(Thread.currentThread().getName() " -- " j);
                }
            }).start();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for (int j = 0; j < 100; j  ) {
                System.out.println(Thread.currentThread().getName() " -- " j);
            }
        }
    }
}
  • 现在有T1、T2、T3三个线程,保证T2在T1执行完后执行,T3在T2执行完后执行。
代码语言:javascript复制
1.设置线程优先级保证让t1,t2,t3按顺序执行,但是它不能保证t1执行完后执行t2而是并行状态
代码语言:javascript复制
// 现在有T1、T2、T3三个线程,保证T2在T1执行完后执行,T3在T2执行完后执行。
class ThreadDemo4 {

    public static void main(String[] args){

        Thread t1 = new Thread(()->System.out.println("1"));
        Thread t2 = new Thread(()->System.out.println("2"));
        Thread t3 = new Thread(()->System.out.println("3"));

        // 1.设置线程优先级保证让t1,t2,t3按顺序执行,但是它不能保证t1执行完后执行t2而是并行状态
        t1.setPriority(8);
        t2.setPriority(5);
        t3.setPriority(1);
        t1.start();
        t2.start();
        t3.start();
    }
}
代码语言:javascript复制
2.使用while死循环监控现场数量,如果t1执行完毕再执行t2,t2执行完执行t3,但是使用线程数量定义是不准确的,所以使用线程状态
代码语言:javascript复制
public static void main(String[] args){

        Thread t1 = new Thread(()->System.out.println("1"));
        Thread t2 = new Thread(()->System.out.println("2"));
        Thread t3 = new Thread(()->System.out.println("3"));
        
        // 2.使用while死循环监控现场数量,如果t1执行完毕再执行t2,t2执行完执行t3,但是使用线程数量定义是不准确的,所以使用线程状态
        t1.start();
        // 定义死循环检查线程数量
        while (true){
            // 如果数量为1则t1线程已经执行完毕执行t2并退出循环
            if (Thread.activeCount() == 1){
                t2.start();
                break;
            }
        }
        // t3同理,等待t2
        while (true){
            if (Thread.activeCount() == 1){
                t3.start();
                break;
            }
        }
}
代码语言:javascript复制
3.使用while死循环监控需要等待线程的状态
代码语言:javascript复制
public static void main(String[] args){

        Thread t1 = new Thread(()->System.out.println("1"));
        Thread t2 = new Thread(()->System.out.println("2"));
        Thread t3 = new Thread(()->System.out.println("3"));

        // 3.使用while死循环监控需要等待线程的状态
        t1.start();
        // 定义死循环检查线程状态
        while (true){
            // 如果t1执行结束,执行t2并退出循环
            if (t1.getState().equals(Thread.State.TERMINATED)){
                t2.start();
                break;
            }
        }
        // t3同理,等待t2
        while (true){
            if (t2.getState().equals(Thread.State.TERMINATED)){
                t3.start();
                break;
            }
        }
}

0 人点赞