有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程java多线程(一个类中的两个同步方法)

我实现了下面的类并获得了以下输出:

dsfs2000  
2000  
b = 1000;

我想知道为什么不是:

b = 1000;  
dsfs2000  
2000

既然t.start()将首先调用m1(),而m2()应该等到m1()完成,为什么m2()实际上首先得到锁

public class TT implements Runnable {
    int b = 100;

    public synchronized void m1() throws Exception{
        //Thread.sleep(2000);
        b = 1000;
        //Thread.sleep(5000);
        System.out.println("b = " + b);
    }

    public synchronized void m2() throws Exception {

        Thread.sleep(2500);
        b = 2000;
        System.out.println("dsfs" + b);
    }

    public void run() {
        try {
            m1();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        TT tt = new TT();
        Thread t = new Thread(tt);

        t.start();
        tt.m2();

        System.out.println(tt.b);
    }
}

共 (3) 个答案

  1. # 1 楼答案

    在代码中

        t.start();  // has to go through the overhead of creating a Thread and calling back its `run`
    
        tt.m2();   // just calling a method on a already created Object, which is really fast
    
  2. # 2 楼答案

    m1()方法的末尾添加notify();,在m2()方法的开头添加wait();,这样就可以了

    这是完整的代码:我改变了两个地方。这是注释// here

    public class TT implements Runnable {
        int b = 100;
    
        public synchronized void m1() throws Exception{
            //Thread.sleep(2000);
            b = 1000;
            //Thread.sleep(5000);
            System.out.println("b = " + b);
            notify(); // here
        }
    
        public synchronized void m2() throws Exception {
            wait(); // here
            Thread.sleep(2500);
            b = 2000;
            System.out.println("dsfs" + b);
        }
    
        public void run() {
            try {
                m1();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) throws Exception {
            TT tt = new TT();
            Thread t = new Thread(tt);
    
            t.start();
            tt.m2();
    
            System.out.println(tt.b);
        }
    }
    

    它是您想要的输出:

    b = 1000
    dsfs2000
    2000
    

    解释:m2()将等待m1()完成作业并通知m2();

  3. # 3 楼答案

    回答您的问题:您的main方法在应用程序的主线程中执行。调用t.start();时,要求JVM组成一个新线程并执行Runable。这是同时发生的,也需要一些时间。调用start方法不会阻止主线程继续执行代码。因此tt.m2()被调用。当JVM创建了一个新线程并开始执行runnable时,runnablesysouts被打印出来。将这种行为形象化。您可以将当前时间添加到system.out.print