Thread.join和Synchronized有什么区别?

JPG*_*JPG 11 java multithreading thread-synchronization

我很困惑何时使用Thread.join()以及何时synchronization在多线程应用程序中使用.

根据我的说法,他们都阻止或等待执行由其他一些线程完成.
这个例子必须依次按顺序模式输出10 A,10 B和10 C:

1  : A
2  : A
3  : A
4  : A
5  : A
6  : A
7  : A
8  : A
9  : A
10 : A
1  : B
2  : B
3  : B
4  : B
5  : B
6  : B
7  : B
8  : B
9  : B
10 : B
1  : C
2  : C
3  : C
4  : C
5  : C
6  : C
7  : C
8  : C
9  : C
10 : C
----ProGraM ENDS----
Run Code Online (Sandbox Code Playgroud)

示例从这里开始

class SyncTest extends Thread 
{   
    StringBuffer sb;

    public SyncTest(StringBuffer sb) 
    {
        this.sb = sb;   
    }

    public void run()
    {
        synchronized(sb) 
        {
            for(int i=1;i<=10;i++){
                System.out.println(i+" : "+sb.charAt(0));
            }
            sb.setCharAt(0, (char) (sb.charAt(0)+1));
        }
    }

    public static void main(String [] args) throws InterruptedException
    {
        StringBuffer sb = new StringBuffer("A");
        Thread t1=new SyncTest(sb);
        Thread t2=new SyncTest(sb);
        Thread t3=new SyncTest(sb);

        t1.start();

        t2.start();

        t3.start();

        Thread.sleep(1000);

        System.out.println("----ProGraM ENDS----");
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里,输出结果是10 A,然后是10 B,接着是10 C,按顺序排列.但我也可以使用Thread.join而不是synchronized块来获得相同的输出:

public void run()
    {
        //removed synchronized statement...

            for(int i=1;i<=10;i++){
                System.out.println(i+" : "+sb.charAt(0));
            }
            sb.setCharAt(0, (char) (sb.charAt(0)+1));

    }

    public static void main(String [] args) throws InterruptedException
    {
        StringBuffer sb = new StringBuffer("A");
        Thread t1=new SyncTest(sb);
        Thread t2=new SyncTest(sb);
        Thread t3=new SyncTest(sb);

        t1.start();
        t1.join();
        t2.start(); // wait for t1 to complete
        t2.join();
        t3.start(); // wait for t2 to complete
        t3.join(); 

                     // wait for t3 to complete
        System.out.println("----ProGraM ENDS----");
    }
Run Code Online (Sandbox Code Playgroud)

任何人都可以清楚我对使用这两种技术的困惑,即何时使用Thread.join以及何时synchronization在Java上使用多线程.

Dun*_*nes 14

Thread.join()等待线程完全完成,而synchronized块可以用来防止两个线程同时执行同一段代码.

一般来说,很难建议何时使用一个,因为它们用于不同的目的.很难找到一个例子,例如你的代码,两者之间的差异很小.

话虽如此,在您的第一个示例中,无法保证输出将按字母顺序排列.您无法确定哪个线程将首先到达synchronized块.所以在这种特殊情况下,join()最合适.

  • @MarkRotteveel你是对的.我温和地编辑了我的答案以反映你的评论.但总的来说,我鼓励OP阅读这个主题,因为除了你的评论涵盖之外还有很多话要说.我的回答并非旨在完整描述`synchronized`的工作原理. (2认同)

Ali*_*ani 6

synchronized关键字启用了一种锁定机制,允许线程不相互踩踏。Java 文档将其描述为“防止线程干扰和内存一致性错误”的一种方法。

如果您使用join(),它可以确保一旦线程调用 join,当前线程(正在运行的线程)将不会执行,除非您调用 join 的线程完成。我认为下图可能有助于更好地形象化这一点。

在此处输入图片说明

来源


The*_*ind 5

thread.join()停止执行当前线程,直到连接的线程完成..你已正确评论.. :)

同步可防止多个线程在同一实例上执行代码的同步部分.