How to improve Java performance using static variables and threads?

In order not to delve into what my software should do, let me just give an example of what I'm trying to decide, to make it short and sweet.

Suppose I have a base class called X, and the implementation of this class, I will call Y. Class Y naturally extends the base class X. Suppose I have 20 objects that will instantiate class Y through a separate thread for each object and with each instance a large file is loaded into memory. Some of these objects may need to use different files, but to make this simple, let's say they all need access to the same file.

Is there a way to define a specific object (variable) that points to these files statically in the base class, so that although the implementation class is loaded 20 times through 20 different threads, they can all use the same static object, so the file needs to be loaded just one time???

Thanks for your help in advance ...

+4
source share
5 answers

If you know the file ahead of time, you can open and load the file in a static initialization block and save the contents in a static data element. Then the content will be available to all instances of this class, regardless of which thread is currently accessing the instance objects.

// In the base class protected static final String fileContents; static { fileContents = readStuffFromFile(); } 
+1
source
  • Is this a read-only file?
  • Is this a big row of data?

if so, and String just make it protected static final String and it is thread safe. if it is changed, you have a whole world of pain in your future.

if it is binary and will be used only in read-only mode, you can probably do the same with byte[] instead of String and make sure that you do not allow anything to change the bytes in the array. The best way would be to implement some Stream or Reader read-only interface.

The easiest and safest way to make something safe for threads is to make it immutable. The final keyword makes links immutable; this does not make the object that it indicates immutable. Since a String immutable, final makes the link immutable, and you're good to go. If you need volatility with changes common to all threads, the java.util.concurrent package will be your friend.

If you make the protected static final variable, then all instances of the subclass, regardless of the thread of execution on which they are located, will see the data.

+5
source

You can start with ConcurrentHashMap .

Make the key to the map a string, and the value should be what the loaded view should be.

Please note: if you changed the downloaded file data, you still need to ensure thread safety, even if you use ConcurrentHashMap.

Initialize this map before creating your objects and pass it to the object constructor.

+1
source

Create a separate object to store the cached contents of the file.

Make this object thread safe as needed by synchronization so that multiple threads can access this object. In base class X, put a reference to this object. Now, multiple instances of class X can be created using the same cached object. Now this requires that this object be loaded only once for each file, and the object can be divided into as many X / Y objects as necessary.

The only problem that remains is the method of loading these files. The solution to this will depend on the structure of your application and these files, but I propose one of the possible solutions.

Create a factory class that will create objects of this new type. This factory will run in its thread, and all downloaded files will be downloaded through this factory. Create an interface in which a file can be requested from this factory. The factory contains a link to all downloaded files, so if it is already loaded, it can immediately return the link back. When not loaded, block the thread Object.wait() call using Object.wait() of the placeholder stored in the factory associated with this file. After the factory file has finished loading, call Object.notifyAll() in the placeholder for this file, which will wake each thread, and these methods will return with a link to the downloaded file.

Once this is completed, each thread that needs a file can simply call a method in the factory to get the file. This thread will block until the file object is loaded, and then the function returns. As long as this is normal, that seems to be the case, as these threads will wait for the file to load anyway, this solution should work well.

0
source

non-static inner class will fulfill all your desires:

 public class Foo { protected String member; public Foo(String member) { this.member = member; } public class Bar { protected String member; public Bar(String member) { this.member = member; } public void show() { System.out.println("this.member: " + this.member + "; Foo.this.member: " + Foo.this.member); } } public static void main(String[] args) throws javax.mail.MessagingException, java.io.IOException { Foo foo_a = new Foo("a"); Foo foo_b = new Foo("b"); Bar bar_a1 = foo_a.new Bar("1"); Bar bar_a2 = foo_a.new Bar("2"); Bar bar_b1 = foo_b.new Bar("1"); Bar bar_b2 = foo_b.new Bar("2"); bar_a1.show(); bar_a2.show(); bar_b1.show(); bar_b2.show(); } } 

Good, good, (-2 votes later):

Firstly, none of the above solutions concerns part of the original question that there cannot be exactly 1 file common to all objects. One group of objects may need to share file A, another group file B, etc. The inner class solution above is designed to fulfill exactly this requirement. You instantiate an outer class once for a file / group, and you create inner objects for a group from the same external object.

Secondly, static is a bad choice: it is likely that the file may need to be specified later at run time, and not when the program starts. The external / internal structure of the class above relates precisely to this problem. Whenever you need, you instantiate an outer class. Static initialization is not required (nor any complex schemes for deferred static initialization).

Thirdly, the thread of paranoia is simply not a problem in this problem (or this is a solution). It is quite clear that the file is read-only, therefore unchanged, therefore, all the simultaneous solution to the problem will only distract from elegant solutions.

Finally, speaking of elegance, this one, and probably the only one.

This update is mainly for someone new who comes in and looks at the stream, as negative voters in this stream are likely to get this down to -5.

-2
source

Source: https://habr.com/ru/post/1340245/


All Articles