同步线程方法同时执行 - 为什么? [英] Synchronized thread method is executing concurrently - why?

查看:113
本文介绍了同步线程方法同时执行 - 为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于线程的问题。我有跟随Thread类并创建2个线程对象。

I have one question about thread. I have following Thread class and creating 2 thread objects.

public class MyThread extends Thread{

    String name="";

    public MyThread(String string) {
        name=string;
    }    

    @Override
    public void run() {
        callMe();
    }       

    synchronized private void callMe() {
        System.out.println("Started");
        for (int i = 1; i <= 5; i++) {
            System.out.println(name+" = "+i);
        }           
    }


    public static void main(String[] args) {            
        MyThread a = new MyThread("A");
        MyThread b = new MyThread("B");

        a.start();
        b.start();
    }       
}

当我执行此操作时,我得到的输出是 -

When I execute this , output I get is -

Started
Started
B = 1
B = 2
A = 1
A = 2
B = 3
A = 3
B = 4
A = 4
B = 5
A = 5

我知道A和B是随机打印的,因为线程调度程序会选择它。

I know that A and B are printed randomly as Thread Scheduler picks it up.

但我的问题是:为什么循环不会一个接一个地执行?我使用了 synchronized 关键字。

But my question is: why loop is NOT executed one after other? I have used synchronized keyword.

推荐答案

您的 synchronized 方法是有效的:

private void callMe() {
    synchronized(this) {
        System.out.println("Started");
        for (int i = 1; i <= 5; i++) {
            System.out.println(name+" = "+i);
        }
    }
}

现在你已经创建了两个不同的实例,所以这个对于每个线程都是不同的......因此它们不会相互同步。如果你想看到两个线程使用相同的监视器,你可以像这样重写你的代码:

Now you've created two different instances, so this will be different for each thread... so they're not synchronizing against each other. If you want to see two threads working with the same monitor, you could rewrite your code like this:

public final class DemoRunnable implements Runnable {
    @Override
    public synchronized void run() {
        System.out.println("Started");
        for (int i = 1; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName() + " = " + i);
        }
    }

    public static void main(String[] args) {
        Runnable runnable = new DemoRunnable();
        Thread a = new Thread(runnable, "A");
        Thread b = new Thread(runnable, "B");
        a.start();
        b.start();
    }
}

然后你会得到这样的输出:

Then you'll get output like this:

Started
A = 1
A = 2
A = 3
A = 4
A = 5
Started
B = 1
B = 2
B = 3
B = 4
B = 5

(当然,它可能是相反的。)

(Although it could be the other way round, of course.)

我们仍然有两个线程,但他们在同一个对象上调用一个synchronized方法(在这种情况下为 DemoRunnable )所以必须等待另一个完成。

We still have two threads, but they're calling a synchronized method on the same object (a DemoRunnable in this case) so one will have to wait for the other to complete.

几点:


  • 实施 Runnable 通常优先于扩展 Thread ;它更灵活

  • 同步线程对象有自己的问题,因为线程 class自己做;试着避免它

  • 我个人不喜欢在上同步这个 - 我通常会有一个类型为<的私有最终变量code> Object 代表我的代码只知道 的监视器......这样我就可以很容易地看到所有代码可以同步它,这使得更容易推理

  • Implementing Runnable is generally preferred over extending Thread; it's more flexible
  • Synchronizing on a Thread object has its own issues, as the Thread class does it itself; try to avoid it
  • Personally I don't like synchronizing on this anyway - I would usually have a private final variable of type Object to represent a monitor that only my code knows about... that way I can easily see all the code that could synchronize on it, which makes it easier to reason about

这篇关于同步线程方法同时执行 - 为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆