方法同步,但由于非序列化的线程行为,代码产生随机结果

Sun*_*jan 2 java multithreading synchronized thread-safety

public class ThreadDemo {

public static void main(String args[]) throws Exception {
    Printer[] printers = new Printer[5];
    printers[0] = new Printer("@base");
    printers[1] = new Printer("#try");
    printers[2] = new Printer("!test");
    printers[3] = new Printer("^hello");
    printers[4] = new Printer("*world");

    for (Printer x : printers) {
        x.start();
    }

    try {
        for (Printer y : printers) {
            y.join();
        }
    } catch (InterruptedException e) {
        System.out.println(e);
    }
  }
}

class Printer extends Thread {
public Printer(String name) {
    super(name);
}

public void run() {
    print();
}

public synchronized void print() {
    for (int i = 0; i < 10; i++) {
        System.out.print(getName().charAt(0));
        try {
            sleep(100);
        } catch (InterruptedException e) {
            System.out.println(e + " occured");
        }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

它导致了

@^!#**@^!#*#@!^@*#^!#^!*@^*@!#@!#*^@#^!*!@^#*#@*^! 
Run Code Online (Sandbox Code Playgroud)

我的期望是所有符号将根据首先启动的线程序列化为@@@@@ ^^^^^.

调用sleep()会让其他线程继续进行直到当前线程的休眠时间,但我想不应该是同步方法的情况.

Gho*_*ica 6

同步不来这里发挥作用.

该关键字确保您不能并行地在同一对象上调用相同的方法.

您正在不同的对象上调用它,因此即使没有关键字,结果也会相同!

(我宁愿假设你看到的结果实际上是由于println()在这里使用造成的.这是一个"非常慢"的操作,它引入了"事实上的"同步,当被超线程快速完成所有其他工作的线程使用时.我正在尝试找到一些关于它的其他信息,但这可能需要更多时间)