Reputation: 601
I have a class with the following class level variables:
private LinkedBlockingQueue<Integer> inputQueue;
private StringBuffer textBuffer;
private int currentIndex;
private String[] p;
private List<String[]> pageList;
private int cursor;
The class has a method setInput() that could be accessed by multiple threads. The method changes all the above variables like this
public void setInput(String s) {
p[cursor] = input;
cursor++;
if (cursor == 1000) {
// UI logic
textBuffer.setLength(0);
p = new String[];
cursor = 0;
}
// Some other logic here
pageList.add(p);
currentIndex++;
if (!inputQueue.offer(currentIndex)) {
throw new RuntimeException();
}
}
These variables can be read by other code snippet in the class, but they are only modified in setInput(). And all the other methods in the class do not have thread safety issue. In other words, they are ensured to be called by the main thread. In this scenario, if I put synchronized keyword before method setInput(), then do I need to use the LinkedBlockingQueue from java.util.concurrent? Are those variables guaranteed to be thread safe when the method is synchronized? Thanks.
Upvotes: 0
Views: 88
Reputation: 12932
No, in your scenario making the setInput
method synchronized
is not enough. All methods accessing the variables need to be synchronized, also the methods which only read the variables, otherwise the variables might be read while setInput
is executing and thus you might see an inconsistent state of the object.
If a lot of threads are reading the variables but only a few are writing them, making the reading methods also synchronized
might be an unnecessary performance bottleneck. In that case it is better to use a ReadWriteLock
, so that all reading threads may access the object at the same time.
Upvotes: 0
Reputation: 135992
To be thread safe, all methods accessing the fields (reading and writing) should be synchronized
Upvotes: 1