Java MULTITHREADING - when multiple threads accesses the print method - why the execution of while method is by default synched
Have a doubt in multithreading. Following is my main program to access 开发者_Python百科a file, am creating 10 threads to be accessed on the object.
public class CallTest {
public static void main(String[] args) throws Exception {
Test t = new Test();
for (int i = 0; i < 10; i++) {
Thread t1 = new Thread(t);
t1.start();
}
}
}
Following is my program to read data from file.
public class Test implements Runnable {
static int i;
public void run() {
try {
i++;
System.out.println("@@@@Count" + i);
print();
} catch (Exception e) {}
}
public void print() {
try {
StringBuilder bufData = new StringBuilder();
File fileTest = new File("D:\\Work\\i466477");
BufferedReader bufferedReader1 = new BufferedReader(new FileReader(
fileTest));
String strRecord = new String();
while ((strRecord = bufferedReader1.readLine()) != null) {
bufData.append(strRecord);
bufData.append("\r");
bufData.append("\n");
}
bufferedReader1.close();
System.out.println("########");
System.out.println(bufData);
} catch (Exception exe) {
System.out.println(exe);
}
}
}
Here I could see the code in the while
is by default synchronized, is BufferedReader
thread safe or because each thread will have their own copy of StringBuilder
and BufferedReader
? I could see the contents are read and written properly.
No, that code won't be synchronized by default. Several threads could each be in the while
loop at the same time. "Synchronized" isn't the same as "working without any problems" - did you think it was synchronized just because you didn't have any issues? In Java, synchronized
is about only allowing one thread to execute certain critical pieces of code at a time in relation to a particular monitor.
Note that your access to i
in the run
method is unsafe, by the way. You should also close the BufferedReader
in a finally
block, and avoid catching Exception
. Finally, your assignment of new String()
to strRecord
to start with is pointless. Hopefully these are just errors due to it being test code, but it's worth being aware of them.
Actually, System.out.println is synchronized. Try this again without those.
Each thread has its own StringBuilder, BufferedReader and FileReader (and operating system level file descriptor) so there won't be any interference at that level. (None of these classes is thread-safe, but the instances are thread-confined so that doesn't matter.)
When you are writing, the PrintWriter.print(...)
and PrintWriter.println(...)
methods are synchronized, and that explains why you don't see output from individual println calls mixed together. (PrintWriter is thread-safe ... and needs to be.)
Note: if you changed your code to include the thread number in each println'ed string, you might occasionally see the output appearing in an unexpected order. Separate calls to a thread-safe method on the same object (the PrintWriter) don't necessarily occur in "first come, first served" order.
The code that updates the static variable i
is not thread-safe, and might give you unexpected (incorrect) results every now and then ... depending on what hardware / JVM you use. You should either do the update in a synchronized static
method, or replace i
with an AtomicInteger
.
Local variables are thread confined. But the non atomic operations(like i++
) on static variable i
is not thread safe.
bufferreader and stringbuilder are not shared between threads, so their use is thread safe.
StringBuffer is thread safe to a degree, in that all its methods are synchronized. BufferedReader is not thread safe.
精彩评论