Private variable shares between objects - java

I have class that looks like
public class Sender {
private LoggingAdapter log = Logging.getLogger(this.toString());
private final ArrayList<CSAMessage> sentHistory = new ArrayList<>();
public void send(final CSAMessage message) {
doSend(message);
sentHistory.add(message);
}
private void doSend(CSAMessage message) {
//do send stuff
}
}
The problem is - when two instances of Sender class are called in same time, they share private sentHistory field. In logs it looks like
Sender1 send(...) was called, message was added to own sendHistory list
Sender2 send(...) was called, message was added to Sender1 sendHistory list
How is that posiible? I'm shure that Sender1 and Sender2 are different instances, they called from different threads, but call was made in same time.
I already tried to make variable 'volatile' - no result
This block gives no result too
private final ArrayList<CSAMessage> sentHistory;
{
sentHistory = new ArrayList<>();
}
Only synchronizing via class helps
public void send(final CSAMessage message) {
synchronized (Sender.class) {
doSend(message);
sentHistory.add(message);
}
}
But this will be performance bottleneck - many Senders must be able to work in same time. And why should i do so? Different instances must use it's own variables!
There are also log variable that has been declared same way, but logging variable not shared between objects, every Sender write logs from it's own name.

Marking the variable final and initializing it the way you did
private final ArrayList<CSAMessage> sentHistory = new ArrayList<>();
// ^^^^^ ^^^^^^^^^^^^^^^^^^^
makes it absolutely impossible for multiple instances to share the same ArrayList.
What remains possible, however, is for multiple ArrayLists to share the same instances of CSAMessage. In cases when shared CSAMessages are mutable, it is possible to create an illusion of sharing. For example, if CSAMessage has a link back to Sender which is set as part of a send call, making a change concurrently may present the message as if it were sent through a wrong sender.

Related

Data Leakage Using InheritableThreadLocal

I'm using a threadpool to run some tasks in my application. Each task contains an object called TaskContext, which looks pretty much like this:
public class TaskContext implements Serializable {
private static InheritableThreadLocal<TaskContext> taskContextTL = new InheritableThreadLocal<>() ;
private final String taskName ;
private final String user;
public TaskContext(String taskName, String user) {
this.taskName= taskName;
this.user = user ;
}
public String getTaskName() {
return taskName ;
}
public static synchronized TaskContext getTaskContext() {
return taskContextTL.get() ;
}
public static synchronized void setTaskContext(TaskContext context) {
taskContextTL.set(context) ;
}
}
I use InheritableThreadLocal because I need the task data to be inherited by children threads.
At the beginning of each task, I use the setTaskContext(new TaskContext(taskName, user)) method to set the task parameters, and before the task ends- I use: setTaskContext(null) to clear this data.
The problem is that for some reason, when the same thread runs a different task, and for that thread I use the getTaskContext().getTaskName() method, I don't get the current task name but some previous task name that this thread ran.
Why is this happening? Why does setting InheritableThreadLocal value to null doesn't clear the data? How it can be avoided?
Thanks a lot for the help
Update:
I found a source online that claims this: "calling set(null) to remove the value might keep the reference to this pointer in the map, which can cause memory leak in some scenarios. Using remove is safer to avoid this issue."
But not sure what it means...
The source that you found that claims "calling set(null) to remove the value might keep the reference to this pointer in the map, which can cause memory leak in some scenarios. Using remove is safer to avoid this issue." is https://rules.sonarsource.com/java/tag/leak/RSPEC-5164.
Although I don't fully understand why they claim this I trust the people from sonarsource.com enough to consider this claim valid.
More to the point of your question they also provide a fix for this problem. Adapted to your code fragment it means that you should not use setTaskContext(null) to remove the TaskContext but rather create a method
public static void clearTaskContext() {
taskContextTL.remove() ;
}
and use this method to remove the TaskContext.
Also note that I didn't make this method synchronized and also the synchronization in getTaskContext() and setTaskContext() is not needed. Since the TaskContext is stored in a ThreadLocal that is (as its name implies) local to a specific thread there can never be a synchronization issue with them

How to make code dynamic for similar kind of blocks

I am creating my web page with vaadin where I need to create same kind of blocks for different type for example need to show blocks having car details, so only car name would be different but the block design would be same with same label but different labels. I want to write generic code so that i can expand it for any car name, without adding it manually.
Attaching the code snippet which i am using where i am repeating my code for different type. Want to implement it dynamically.
private Grid<PresentableGenerateInputHeaders> winTSHeaderColumnsGrid;
private Grid<PresentableGenerateInputHeaders> fRHeaderColumnsGrid;
private ListDataProvider<PresentableGenerateInputHeaders> listDataProvider;
private List<PresentableGenerateInputHeaders> presentableGenerateInputHeaders = new ArrayList<>();
private void initWinTsGrid() {
listDataProvider = new ListDataProvider<>(presentableGenerateInputHeaders);
winTSHeaderColumnsGrid = new Grid<PresentableGenerateInputHeaders>(PresentableGenerateInputHeaders.class);
winTSHeaderColumnsGrid.setDataProvider(listDataProvider);
winTSHeaderColumnsGrid.setCaption(i18n.get("view.ruleDetails.general.csvHeaderColumns"));
winTSHeaderColumnsGrid.setStyleName("a-units");
winTSHeaderColumnsGrid.setWidth("450px");
winTSHeaderColumnsGrid.setItems(addGridValues(DataSource.WIN_TS, winTSHeaderColumnsGrid));
winTSHeaderColumnsGrid.getEditor().setEnabled(true);
winTSHeaderColumnsGrid.setColumnOrder("header", "count");
winTSHeaderColumnsGrid.sort("header");
winTSHeaderColumnsGrid.getEditor().addSaveListener((EditorSaveEvent<PresentableGenerateInputHeaders> event) -> {
event.getGrid().select(event.getBean());
selectedGapFillingCountWINTS.add(event.getBean());
});
}
private void initFRGrid() {
listDataProvider = new ListDataProvider<>(presentableGenerateInputHeaders);
fRHeaderColumnsGrid = new Grid<PresentableGenerateInputHeaders>(PresentableGenerateInputHeaders.class);
fRHeaderColumnsGrid.setDataProvider(listDataProvider);
fRHeaderColumnsGrid.setCaption(i18n.get("view.ruleDetails.general.csvHeaderColumns"));
fRHeaderColumnsGrid.setStyleName("a-units");
fRHeaderColumnsGrid.setWidth("450px");
fRHeaderColumnsGrid.setItems(addGridValues(DataSource.FR, fRHeaderColumnsGrid));
fRHeaderColumnsGrid.getEditor().setEnabled(true);
fRHeaderColumnsGrid.setColumnOrder("header", "count");
fRHeaderColumnsGrid.sort("header");
fRHeaderColumnsGrid.getEditor().addSaveListener((EditorSaveEvent<PresentableGenerateInputHeaders> event) -> {
event.getGrid().select(event.getBean());
selectedGapFillingCountFR.add(event.getBean());
});
}
You can change methods to be more generic by identifying all the parts you don't want to keep static, and moving those to be populated by method parameters instead. I.e. instead of
private void myMethod() {
grid.setCaption("myCaption");
}
you would write
private void myMethod(String caption) {
grid.setCaption(caption);
}
and then call it
myMethod("myCaption");
If you need to be outside of the whole class to be able to determine what the real values are, you can for example make the method public or pass on the necessary values in the class constructor.
public MyClass(String gridCaption) {
myMethod(gridCaption);
}
If there are a lot of values you need to set dynamically, you might consider using an object that contains all the necessary values instead.
public void myMethod(MyPojo pojo) {
grid.setCaption(pojo.getGridCaption());
}
In your example it looks like the generic values you want to pass are DataSource dataSource and whatever type of collection selectedGapFillingCountWINTS and selectedGapFillingCountFR happen to be, and the method should probably return the grid rather than set it directly to a class variable.

AWS Java Lambda local variables vs object variables

I am trying to find answer to a very specific question. Trying to go through documentation but so far no luck.
Imagine this piece of code
#Override
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
Request request = parseRequest(input);
List<String> validationErrors = validate(request);
if (validationErrors.size() == 0){
ordersManager.getOrderStatusForStore(orderId, storeId);
} else {
generateBadRequestResponse(output, "Invalid Request", null);
}
}
private List<String> validate(Request request) {
orderId = request.getPathParameters().get(PATH_PARAM_ORDER_ID);
programId = request.getPathParameters().get(PATH_PARAM_STORE_ID);
return new ArrayList<>();
}
Here, I am storing orderId and storeId in field variables. Is this okay? I am not sure if AWS will cache this function and hence cache the field variables or would it initiate a new Java object for every request. If its a new object, then storing in field variable is fine but not sure.
AWS will spin up a JVM and instantiate an instance of your code on the first request. AWS has an undocumented spin down time, where if you do not invoke your Lambda again within this time limit, it will shut down the JVM. You will notice these initial requests can take significantly longer but once your function is "warmed up", then it will be much quicker.
So to directly answer your question, your instance will be reused if the next request comes in quick enough. Otherwise, a new instance will be stood up.
A simple Lambda function that can illustrate this point:
/**
* A Lambda handler to see where this runs and when instances are reused.
*/
public class LambdaStatus {
private String hostname;
private AtomicLong counter;
public LambdaStatus() throws UnknownHostException {
this.counter = new AtomicLong(0L);
this.hostname = InetAddress.getLocalHost().getCanonicalHostName();
}
public void handle(Context context) {
counter.getAndIncrement();
context.getLogger().log("hostname=" + hostname + ",counter=" + counter.get());
}
}
Logs from invoking the above.
22:49:20 hostname=ip-10-12-169-156.ec2.internal,counter=1
22:49:27 hostname=ip-10-12-169-156.ec2.internal,counter=2
22:49:39 hostname=ip-10-12-169-156.ec2.internal,counter=3
01:19:05 hostname=ip-10-33-101-18.ec2.internal,counter=1
Strongly not recommended.
Multiple invocations may use the same Lambda function instance and this will break your current functionality.
You need to ensure your instance variables are thread safe and can be accessed by multiple threads when it comes to Lambda. Limit your instance variable writes to initialization - once only.

Static ArrayList does not modify in another class

I am working on a client - server application and I have the following problem.
In one class (Server), I have a static reference to an ArrayList called clients and a static getter getClientsArray(). In another class (ServerThread), I use the same ArrayList and I successfully modify it (add / delete clients).
For every client, I call the method getClientsArray() and get that ArrayList. The problem is that the ArrayList is empty here, in Client class. I check it every time I update it in ServerThread (after a client connects) and it should have something in it.
public class Server {
private static ArrayList<User> clients = new ArrayList<User>();
public static ArrayList<User> getClientsArray() {
return clients;
}
and somewhere I call: new ServerThread(sock, users).start();
}
public class ServerThread extends Thread {
private ArrayList<User> users;
public ServerThread(Socket client, ArrayList<User> users) {
this.client = client;
this.users = users;
}
if I modify users in this class, the changes will occur
}
public class Client extends JFrame {
private ArrayList<User> users;
public Client() {
initGraphics();
users = Server.getClientsArray();
System.out.println(users.size()); <- This line always writes 0!!
}
}
There is a simple rule defined by Brian Goetz in JCIP:
If multiple threads access the same mutable state variable without appropriate synchronization, your program is broken.
You have clients mutable state and you don't use any mean of synchronizing access to it.
Static variables are only global to one program instance. Here, you have at least two programs running; You have one server program, and at least one other client program. The clients and server do not share any common heap, or program variables, so the static list will only be seen by that program.
If you want to share the list, you will need to pass it through sockets or some other data transfer. This question, How to transfer objects over network using java, has a code example of how to pass objects through sockets.

Java Static Factory conversion

On my Client/Server Desktop application. I have this problem of how I should properly code my JDBC class with my Models to ensure all persistence request can support concurrency. i.e., multiple models want to request update to its persistence counterpart simultaneously [without atmost delay].
The scenario goes like this. Following the classes located in the server application.
Persitence Package:
abstract class AbstractService {
// other fields
private final String tName, tId;
private final String sqlStatement;
public AbstractService(final String tName, final String tId) {
this.tName = tName;
this.tId = tId;
this.sqlStatement = ""; // SELECT statement
}
// java.sql.Connection() createConnection()
// methods
}
public class T1Service extends AbstractService {
private final String sqlDMLStatements;
public T1Service() {
super("t1", "t1Id");
this.sqlDMLStatements = ""; // other DML statements
}
// methods having return types of List<E>, Object, Boolean, etc.
// i.e., public List<E> listAll()
}
Communication class [Client class]
import java.net.*;
import java.io.*;
public class Client extends Observable{
private Socket socket;
private ObjectInputStream input;
private ObjectOutputStream output;
private Object message;
// Constructor
// Getters/Setters
// Other methods like open or close input/output
private class ReceiverRunnable implements Runnable
#Override
public void run() {
while(running) { // if socket is still open and I/O stream are open/initialized
try { message = input.readObject(); }
catch(Exception e) {}
finally { setChanged(); notifyObservers(); }
}
}
}
}
The Main Class [Server class]
import java.net.*;
public class Server {
private List<Client> clientList; // holds all active connections with the server
private T1Service t1Service
private class ConnectionRunnable implements Runnable {
#Override public void run() {
while(running) { // serverSocket is open
Client client = new Client(ServerSocket.accept(), /* other parameters */);
client.addObserver(new ClientObserver(client));
clientList.add(client);
}
}
}
private class ClientObserver implements Observer {
private Client client;
// Constructor
public void update(Observable o, Object arg) {
// Check the contents of 'message' to determine what to reply
// i.e., message.equals("Broadcast") {
// synchronized(clientList) {
// for(Client element : clientList) {
// element.getOutput().writeObject(replyObject);
// element.getOutput()..flush();
// }
// }
// i.e., message.equals("T1") {
// synchronized(t1Service) {
// client.getOutput().writeObject(t1.findAll());
// client.getOutput().flush();
// }
}
}
}
Since this is a Client/Server applcation, multiple request from the client are simultaneously feed to the server. The server process the request sending the appropriate reply to the approriate client. Note: All of the objects sent between Client & Server an instance of java.io.Serializable.
Having this kind of scenario and looking into the block of Server.ClientServer.update() we may have a performance issue or I should say a delay in processing the N client(s) request due to Intrinsic Locks. But since I have to the rules concurrency and synchronization to ensure that Server.T1Service won't get confused to the queue of N clients request to it. Here's are the questions:
According to the Item 1 of Effective Java - Second Edition regarding Static Factory, would this let me create a new class reference to the methods inside the classes of Persistence package?
Would each Client element inside List<Client> would form a concurrency issue having N client update their message field simultaneously triggering the ClientObsver.update() wherein the reference object(s) of this Observer is only a single instance in the parent class. I was avoiding creating multiple instance of T1Service due to memory concerns.
If we are going to go by the contents of Effective Java - Second Edition, how can I convert my persitence class in a way they can be read easily, easily instantiated, and support concurreny?
you may also want to review Actors, for example ones in Akka
basic idea of actors is avoiding of synchronization at all, using sending events. Akka will guarantee that one actor will never be invoked by two threads in parallel. So you may define actor, which does something with the global variables, and then simply send a message to it.
works like a charm usually :)
Is my theory of [Item 1] Static Factory correct?
Yes, you can use a static factory instead of constructors. Typically this is when you the construction logic is complex and shared between various subtypes to warrant a factory pattern. Additionally the factory may provide means for dependency injection outside of a DI framework.
Would it then solve the concurrency issue of the converted static factory global objects?
If you need to synchronize construction, then a static factory works well, just add synchronized to the method declaration on your factory methods. If you need to synchronize methods on the objects themselves then this will not help.
Is it advisable for me to convert to static factory if where dealing with concurrent access to a global object and where wanted real-time access to the methods of each global object?
As I answered above, it depends on what you are trying to achieve. For constructor synchronization use a factory.

Categories