I can not understand why the messages are not displayed in the order in which they were created, that is, obj1, obj2, obj3 in main are created one after the other and initialized "1", "2", "3", respectively, but when started, it is not "1 , 2,3 ", and" 1,3,2 ", and if you create objects in the order of obj1, obj3, obj2, then everything is displayed as it should, that is," 1,2,3 ". How many I don’t look at the code, but I don’t see a problem (or don’t know what to look for, as I just started to learn multithreading).

public class Main { public static void main(String[] args) { Callme target = new Callme(); Caller obj1 = new Caller(target, "1"); Caller obj2 = new Caller(target, "2"); Caller obj3 = new Caller(target, "3"); try { obj1.t.join(); obj2.t.join(); obj3.t.join(); } catch (InterruptedException e) { System.out.println("Прервано"); } } } class Callme { synchronized void call(String msg) { System.out.print("[" + msg); try { Thread.sleep(500); } catch (InterruptedException e) { System.out.println("Прерван"); } System.out.println("]"); } } class Caller implements Runnable { String msg; Callme target; Thread t; public Caller(Callme targ, String s) { target = targ; msg = s; t = new Thread(this); t.start(); } @Override public void run() { target.call(msg); } } 

    1 answer 1

    Synchronization ensures that the code in the synchronized method (or block) is not executed simultaneously by multiple threads. But you run three threads, and no one gives guarantees which one of them will be the first to execute the call method code.

    Specifically, in your example, if you remove the word synchronized in the call method, the square brackets may not close after each digit, because

     void call(String msg) { System.out.print("[" + msg); // один поток начинает выполнять call, выводит скобочку и циферку try { Thread.sleep(500); // этот поток засыпает } catch (InterruptedException e) { System.out.println("Прерван"); } System.out.println("]"); // когда он просыпается, другой поток уже успел вывести свою скобочку и циферку } 

    Please note that synchronization always uses the object for blocking. In the case of synchronization blocks, the object is specified explicitly, in the case of methods (your case), this object is the instance on which the method is called.

    Therefore, your example will work as long as all three threads refer to the call method of the same Callme object. If you create a separate Callme for each Caller , then synchronization will not work.

    • Everything is clear, but what if you need to display the message exactly as needed? Is it somehow related to the priorities of the threads? - Nathan Light
    • @NathanLight You can just do it in one thread) - selya
    • @NathanLight, >> if you need to display a message exactly as you need it? << various synchronization methods will come to the rescue - signals, semaphores or even IpC. Choose the most understandable way for you, which will not seem redundant and costly, and add to the code. - test123