2

正如我们所知,没有任何规定可以防止多个线程run()使用方法调用该start()方法。我确实创建了两个对象m1,并且m2都调用同一个线程来运行。

m1.start我需要通过在第二个对象执行开始之前调用线程来确保第一个对象完成( )它的执行。

我的问题是为什么我不能在我创建的线程中使用synchronized关键字 with方法(即)?run()MyThread1

我尝试在我创建的线程中使用“同步”来运行()方法,但它给出了任意输出(换句话说m2,不等待m1完成执行)。

您可以在程序的最底部看到我得到的输出。

public class ExtendedThreadDemo {

    public static void main(String[] args) {    
        Mythread1 m1 =new Mythread1();
        Mythread1 m2 =new Mythread1();
        m1.start();
        m2.start();
        System.out.println(" main thread exiting ....");
    }
}

我的线程

public class MyThread1 extends Thread {

    public synchronized void run() {
        for(int i=1; i<5; i++) {
            System.out.println(" inside the mythread-1 i = "+ i);
            System.out.println(" finish ");

            if (i%2 == 0) {
                try {
                    Thread.sleep(1000);
                } catch(InterruptedException e) {
                     System.out.println(" the thread has been interrupted ");
                }
            }
        }
    }
}

输出

main thread exiting ....
inside the mythread-1 i = 1
finish
inside the mythread-1 i = 2
finish 
inside the mythread-1 i = 1
finish 
inside the mythread-1 i = 2
finish 
inside the mythread-1 i = 3
finish 
inside the mythread-1 i = 4
finish 
inside the mythread-1 i = 3
finish 
inside the mythread-1 i = 4
finish 

如您所见i = 2,第二个对象(即m2.start())开始执行。

4

3 回答 3

2

打电话m1.join()main先打电话m2.start()

创建方法synchronized只会影响对同一对象上方法的多次调用;m1m2是不同的对象,所以添加synchronized不会有任何效果。

于 2012-05-26T14:58:25.053 回答
0

A synchronized instance method only hinder concurrent access to the same instance of the class. You would see your expected effect if the run method was static. But I do not suggest making the run method static. In fact you cannot if it is to keep its current functionality. What you should instead consider is using m1.join() to wait for m1 to finish. Another approach which works better if you have multiple threads which are to wait for each other is to use a CyclicBarrier or a CountDownLatch.

于 2012-05-26T15:03:01.443 回答
0

此代码片段:

public synchronized void run() {
  //code
}

在语义上等价于:

public void run() {
  synchronized(this) {
    //code
  }
}

注意this参考。这意味着synchronized使用相同this引用(锁定对象)的所有块都是互斥的。this但是,您正在创建两个线程(对象),每个线程都在不同的引用上同步。

有几种方法可以改进您的代码:

只使用一个Runnable并创建两个线程:

public class Mythread1 implements Runnable //...

接着:

Runnable r = new Mythread1();
Thread m1 = new Thread(r);
Mythread1 m2 = new Thread(r);

但这只有在Mythread1runnable 是 statelss 时才有效,因为它将由两个线程共享。

使用同一个锁实例

将一些任意lock对象传递给两个实例,Mythread1然后使用:

synchronized(lock) {
  //code
}

从 Java 5 开始,同步代码的方法要复杂得多,但这种方法适用于简单的情况。

利用Thread.join()

您可以致电:

m1.start();
m1.join();
m2.start();

这会成功的。

于 2012-05-26T15:01:12.093 回答