5 一个线程面试题中代码遇到的问题

六星官方社区工作人员 发布于 2019-12-28 16:28
阅读 958
收藏 0
分类:面试与就业

一个线程面试题中代码遇到的问题

三个人跑步,依次翻越障碍,必须3个人都翻阅一个时候,大家才能翻阅下一个。

我代码基本实现,但是有个问题。


import java.util.Random;


public class ThreadNumber {

//存有三个人跑的距离

public static class Num {

int m = 1;

int j = 1;

int g = 1;


}


/**

 * 线程交替标识,true跑完了

 */



/**

 * 打印奇数的线程类

 */

public static class Mming implements Runnable {

    Num num;

//此段是否跑完

    boolean flagM = false;


    public Mming(Num num) {

        this.num = num;

    }


    @Override

    public void run() {

        while (num.m <= 3) {

            if ((!flagM)) {

                System.out.println("m开始跑" + num.m + "个" + current());


                int time = randomNum();

                try {

                    Thread.sleep(time);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }


                System.out.println("Mming花了" + time + "跑完第" + num.m + "个" + current());

                num.m++;

                flagM = true;

//检查另外两人是否跑完

if (num.j >= num.m && num.g >= num.m) {

flagM = false;

}


            } else {

                if (num.j >= num.m && num.g >= num.m) {

                    flagM = false;

                }

                System.out.println("!!!!!!!");

            }

        }


    }

}


/**

 * 打印偶数的线程类

 */

public static class Jordan implements Runnable {

    Num num;

    boolean flagJ = false;


    public Jordan(Num num) {

        this.num = num;

    }


    @Override

    public void run() {

        while (num.j <= 3) {


            if ((!flagJ)) {

                System.out.println("j开始跑" + num.j + "个" + current());


                int time = randomNum();

                try {

                    Thread.sleep(time);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }


                System.out.println("Jordan花了" + time + "跑完第" + num.j + "个" + current());

                num.j++;

                flagJ = true;

                if (num.m >= num.j && num.g >= num.j) {

                    flagJ = false;

                }


            } else {

                if (num.m >= num.j && num.g >= num.j) {

                    flagJ = false;

                }

                System.out.println("!!!!!!!");

            }


        }

    }

}


public static class Guai implements Runnable {

    Num num;

    boolean flagG = false;


    public Guai(Num num) {

        this.num = num;

    }

    @Override

    public void run() {

        while (num.g <= 3) {

            if ((!flagG)) {

                System.out.println("g开始跑" + num.g + "个" + current());

                int time = randomNum();

                try {

                    Thread.sleep(time);


                } catch (InterruptedException e) {

                    e.printStackTrace();

                }


                System.out.println("Guai花了" + time + "跑完第" + num.g + "个" + current());

                num.g++;

                flagG = true;

                if (num.m >= num.g && num.j >= num.g) {

                    flagG = false;

                }

            } else {

                if (num.m >= num.g && num.j >= num.g) {

                    flagG = false;

                }

                System.out.println("!!!!!!!");

            }

        }


    }

}


volatile static Num num = new Num();


public static void main(String[] args) {

    new Thread(new Guai(num)).start();

    new Thread(new Mming(num)).start();

    new Thread(new Jordan(num)).start();

    

}


public static int randomNum() {

    Random rand = new Random();


    return rand.nextInt(1000) + 1000;

}



public static String current() {


    return Long.toString(System.currentTimeMillis());


}

}


这段代码执行可以,但是如果把 System.out.println("!!!!!!!");删除。执行就会卡死。完全搞不明白为什么!!!!!!!求助

最佳答案 2020-03-24 17:16

53
六星官方社区工作人员
六星官方社区工作人员

这个应该是可见性的问题,尝试在Num类的三个变量上加上volatile,你在外围的对象num上加了volatile,作用是num引用发生变化了,才会同步主内存,线程工作内存失效,你改变里面的值并不会发生上面的操作;为什么用了System.out.println("!!!!!!!");这个也可以呢?这是因为System.out.println()这个方法底层用到了synchronized关键字

请先 登录 后评论