确定线程的顺序

时间:2014-08-09 10:07:25

标签: java multithreading

我发现了Thread这个问题。我认为可能正确的答案是abc123和123abc。如何将a1bc23作为正确答案?

所述方法是同步静态方法。因此,如果线程字母或数字抓住了密钥,它应该访问该类的密钥。一旦抓住它,它将不会释放密钥,直到线程完成。那么a1bc23这样的答案怎么会来?在这种情况下,线程是否可以访问类线程?

public class ExamQ32 {
    public static synchronized void say(String s) {
        System.out.print(s);

    }
    public static void main(String[] args) {
        Thread letters = new Thread() {
            public void run() {
                say("a");
                say("b");
                say("c");
            }
        };

        Thread numbers = new Thread() {
            public void run() {
                say("1");
                say("2");
                say("3");
            }
        };
        letters.start();
        numbers.start();
    }
}

4 个答案:

答案 0 :(得分:3)

每个线程都有say方法的不同调用。正如您在documentation中所读到的那样,synchronized关键字指定两个Threads无法同时执行该方法。但是当say("a")调用返回时,另一个线程可以执行。

首先启动letters通常首先输入say方法,numbers将阻止say("1")直到{{} 1}}完成。之后say("a")将继续执行numbers方法(并阻止say输入,阻止它直到letters退出方法)。

因此,您通常会在输出中看到交错的字母和数字。

答案 1 :(得分:3)

我认为可能正确的答案是,abc123和123abc

唔不,让我们来看看你在做什么。

public static synchronized void say(String s) {
    System.out.print(s);

}

上面的代码指定 only 一个线程一次可以执行此方法。当一个线程完成其say()时,任何其他线程都可以执行它。

现在,

     Thread letters = new Thread() {
        public void run() {
            say("a");
            say("b");
            say("c");
        }
    };

    Thread numbers = new Thread() {
        public void run() {
            say("1");
            say("2");
            say("3");
        }
    };

创建2个线程,需要注意的重要事项是say("a")say("b")say("c")不能保证连续执行。它们在同一个线程中运行但不能保证一个接一个地执行。当say("a")完成时,线程字母可能暂停并且线程编号可能会开始执行。因此,您的输出无法保证。

要获得预期的输出,您需要在每个运行方法中锁定ExamQ32.class(如下所示),因为say()是静态的 将代码更改为以下内容以获得预期的输出:

public class ExamQ32 {
public static void say(String s) {
    System.out.print(s);

}

public static void main(String[] args) {
    Thread letters = new Thread() {
        public void run() {
            synchronized (ExamQ32.class) {
                say("a");
                say("b");
                say("c");
            }
        }
    };

    Thread numbers = new Thread() {
        public void run() {
            synchronized (ExamQ32.class) {
                say("1");
                say("2");
                say("3");
            }
        }
    };
    letters.start();
    numbers.start();
}

}

答案 2 :(得分:2)

线程中对say()方法的所有三次调用都不同步。对方法执行完成后,对synchronized方法say()的单独调用将获取锁并释放它。

因此,当Thread1-> say()完成执行时,锁定被释放,可以由Thread2->say()获取。

要获得类似abc123123abc的输出,您需要在所有三个调用中进行同步。

public static void main(String[] args) {
        Thread letters = new Thread() {
            public void run() {
              synchronized(ExamQ32.class){
                say("a");
                say("b");
                say("c");
              }
            }
        };

        Thread numbers = new Thread() {
            public void run() {
              synchronized(ExamQ32.class){
                say("1");
                say("2");
                say("3");
              }
            }
        };
        letters.start();
        numbers.start();
    }

答案 3 :(得分:2)

你单独调用say()。对于每次调用,它获取锁并释放锁。如果您想要更可预测的输出,请按如下方式修改程序

public class ExamQ32 {

     private static Object lock = new Object();

        public static  void say(String s) {
            System.out.print(s);

        }
        public static void main(String[] args) {
            Thread letters = new Thread() {
                public void run() {
           sychronized(lock){
                    say("a");
                    say("b");
                    say("c");
                  }
                }
            };

            Thread numbers = new Thread() {
                public void run() {

            synchronized(lock){
                    say("1");
                    say("2");
                    say("3");
                    }
                }
            };
            letters.start();
            numbers.start();
        }
    }

它将确保输出为" abc123"或" 123abc"