java Thread.join 和 Synchronized 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27244677/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between Thread.join and Synchronized?
提问by JPG
I am confused when to use Thread.join()
and when to use synchronization
in multi threading application.
我很困惑何时使用Thread.join()
以及何时synchronization
在多线程应用程序中使用。
According to me, both of them block or wait for the execution to be done by some other thread.
This example has to output 10 A's , 10 B's & 10 C's in sequential pattern one after other like :
据我说,它们都阻塞或等待其他线程完成执行。
此示例必须以顺序模式一个接一个地输出 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----
Example starts here
示例从这里开始
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----");
}
}
Here, output turns out to be 10 A's followed by 10 B's followed by 10 C's in a sequential order. But I can also use Thread.join
instead of synchronized
block to get the same output like this:
在这里,输出结果是 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----");
}
Can anyone clear my confusion on usage of these 2 techniques i.e. when to use Thread.join
and when to use synchronization
in Multi-threading on Java.
任何人都可以清除我对这两种技术的使用的困惑,即何时使用Thread.join
以及何时synchronization
在 Java 多线程中使用。
回答by Duncan Jones
Thread.join()
waits for the thread to completely finish, whereas a synchronized
block can be used to prevent two threads from executing the same piece of code at the same time.
Thread.join()
等待线程完全完成,而synchronized
块可用于防止两个线程同时执行同一段代码。
It's hard to advise when to use one over the other in general, since they serve different purposes. It's rare to find an example, such as your code, where the difference between the two is minimal.
一般来说,很难建议何时使用一种而不是另一种,因为它们用于不同的目的。很难找到一个示例,例如您的代码,其中两者之间的差异很小。
That being said, in your first example there is no guarantee the output will be alphabetical. You can't be sure which thread will get to the synchronized
block first. So in this particular case, join()
is most appropriate.
话虽如此,在您的第一个示例中,不能保证输出是按字母顺序排列的。您无法确定哪个线程将首先到达该synchronized
块。所以在这种特殊情况下,join()
是最合适的。
回答by TheLostMind
thread.join()
stops the execution of current threaduntil the joined thread completes.. You have commented correctly.. :)
thread.join()
停止当前线程的执行,直到加入的线程完成.. 您已正确评论.. :)
Synchronizationprevents multiplethreads from executing the synchronized part of code on the same instance.
同步可防止多个线程在同一实例上执行代码的同步部分。
回答by Ali Gajani
The synchronized
keyword enables a locking mechanism that allows threads to not step on each other. Java documentation describes this as a way to " preventing thread interference and memory consistency errors".
该synchronized
关键字启用了一种锁定机制,该机制允许线程不相互踩踏。Java 文档将其描述为“防止线程干扰和内存一致性错误”的一种方法。
If you use join()
, it makes sure that as soon as a thread calls join,the current thread(running thread) will not execute unless the thread you have called join is finished. I think the diagram below might help visualize this better.
如果您使用join()
,它确保一旦线程调用 join,当前线程(正在运行的线程)将不会执行,除非您调用 join 的线程完成。我认为下图可能有助于更好地形象化这一点。
回答by Ashish Rawat
Without join()
thread runs in parallel and depend upon OS time slice (which to start first). With join()
thread runs in series. For eg:
Suppose you have two threads with both calling join()
method
没有join()
线程并行运行并依赖于操作系统时间片(首先启动)。与join()
线程串联运行。例如:假设你有两个线程,两个调用join()
方法
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.join(); // this will be start first.
t2.join(); // this will be start only after above.
Now without join()
method, any of t1
and t2
can start first. There's is no guarantee.
现在没有join()
方法,任何的t1
和t2
可以先启动。没有任何保证。
synchronized
statement/keyword is used for monitoring the thread, so that only one thread can access that synchronized method/variable at a time. It doesn't matter if you use join()
or not.
synchronized
语句/关键字用于监视线程,以便一次只有一个线程可以访问该同步方法/变量。用不用都无所谓join()
。
If you use synchronized
with join()
, you have a guarantee that thread t1
can only access first. Without synchronized
both t1
and t2
thread can access at any time but these threads start and die. in series because of join()
.
如果使用synchronized
with join()
,则可以保证线程t1
只能首先访问。如果没有synchronized
这两个t1
,并t2
在任何时候线程可以访问,但这些线程启动和模具。串联,因为join()
。
回答by stdout
They are obviously NOT the same but, if they are going to be used for the same purpose (serializing access/execution ) then synchronized blocks can be thought as a more flexible version than using joins since it's usage is agnostic about particular thread instances on which you want to serialize execution.
它们显然不一样,但是,如果它们将用于相同的目的(序列化访问/执行),那么同步块可以被认为是比使用连接更灵活的版本,因为它的用法与特定线程实例无关你想序列化执行。
Moreover, in synchronized blocks the shared data block concept is more emphasized than joins.
此外,在同步块中,共享数据块的概念比连接更强调。
回答by Java Main
Simple example :
简单的例子:
You have a static string table where some threads will be putting some values . The table is initialized with "empty" . the table is accessed with a static index. If a thread puts a value, it will increment the static index .
您有一个静态字符串表,其中一些线程将放置一些值。该表被初始化为 "empty" 。使用静态索引访问该表。如果一个线程放置一个值,它将增加静态索引。
If you synchronize the threads it will make sure that any value put by a thread can not be overriden by another thread .
如果同步线程,它将确保一个线程放置的任何值都不会被另一个线程覆盖。
if you use join on threads, only the first joinded thread will have the opportunity to put the values in the table .As the other will be waiting but knowing that the index is incremented they wont be able to access the table (null pointer exception) . So Join has made the other thread useless.
如果您在线程上使用连接,则只有第一个连接的线程才有机会将值放入表中。因为另一个将等待但知道索引增加,他们将无法访问该表(空指针异常) . 所以Join已经让另一个线程没用了。
This example uses threads on same instance containing the synchronized method.
此示例在包含同步方法的同一实例上使用线程。