As known that List is not thread-safe, I add synchronized to the code in 2 methods shown below.
1.
public class TestSyn
{
public static void main( String[] args ) throws InterruptedException
{
List<String> list = new ArrayList<>();
for( int i = 0; i < 100000; i++ )
{
new Thread(
()->
{
synchronized( list )
{
list.add( Thread.currentThread().getName() );
}
} ).start();
}
Thread.sleep( 2000 );
System.out.println( list.size() );
}
}
public class TestSyn2
{
public static void main( String[] args ) throws InterruptedException
{
List<String> list = new ArrayList<>();
synchronized( list )
{
for( int i = 0; i < 10000; i++ )
{
new Thread( () -> list.add( Thread.currentThread().getName() ) )
.start();
}
}
Thread.sleep( 2000 );
System.out.println( list.size() );
}
}
The result of the first method was always 10000 which was correct,while the second one sometimes is less than 10000.
So, why does the second one cannot output the right result?
Just expanding on the answer that already was provided in comments (above).
The difference between your two versions is in which thread or threads lock the
listobject's intrinsic mutex.In the first version, the
synchronized(list)statement is executed by each one of the 100,000 new threads that your program creates. It is lexically contained within the lambda expression that generates theRunnabledelegates for each of the new threads.In the second version, the
synchronized(list)statement is only ever executed one time, by the program'smainthread. It appears outside of the lambda. The 100,000 new threads mutate the shared list without any synchronization, and the fact thatmain()executes inside thesynchronizedblock means nothing because no other thread ever tries to synchronize on the same object.Also note: Although the first version of your program is "safe," it also is kind of pointless. None of your 100,000 new threads ever does anything at all outside of the
synchronizedblock. That means, none of your 100,000 new threads ever does anything concurrently with any of the others. But concurrency is the only reason for creating threads.