Static variables, threads and constructor Java - java

I have seen this from a recognised sample book so its hard to question then there is something I dont understand.
A class called DataflightsService contains a private static variable called FlightFileAccess that appears to be instantiated everytime we create a new object for DataflightsService as FlightFileAccess's initiation its in the constructor
ie
public class DataflightsService{
private static FlightFileAccess fileAccess=null;
public DataflightsService(String path){
fileAccess=new flightFileAccess(path);
}
public boolean removeflight(String code){
//We use this static instance that wraps functionality to remove a flight
fileAccess.remove(code);
}
}
For me that means that every time we create an instance of DataflightsService, in the constructor are using a different object all the time for the static variable FlightFileAccess
In the original FlightFileAccess Class: we have the remove method that synchronizes a RandomAccessFile
Class FlightFileAccess{
private RandomAccessFile database = null;
private boolean remove(String code){
// Other code goes here and there
synchronized (database) {
//Perform deletion code
}
}
So because we are using a different reference of FlightFileAccess we are also using a different reference of RandomAccessFile?
That means that having FlightFileAccess as static in service does not serve here to synchronize on the RandomAccessFile because it is a new one every time so each DataflightsService instance will do their thing on the random access file ignoring the synchronization.
As opposed to instantiating FlightFileAccess in a static initiator. Am I right?
I would appreciate as many explanations as possible to provide the best way to be able to instantiate DataflightsService as many times as we want (as lets say imagining each client has their own instance of DataflightsService) and after that being able to synchronize on a file for removals for example so that there is no mess of several clients accessing the file. Sorry I need to include a DataflightsService per client bc there are no cookies.

Your example won't compile because the name of the constructor doesn't match the class. But if you mean to name the constructor public DataflightsService(), then part of the issue is that you are overwriting the static variable each time a new object is created.
It sounds like you want this static variable to be initialized only once. Normally you would just assign the variable directly with private static final FlightFileAccess fileAccess = new FlightFileAccess(); or if you wanted to add more logic as if you had a constructor, you could use a static initializer block as follows:
public class Dataflights {
private static final FlightFileAccess fileAccess;
static {
// Static initializer block gets run once when the class is first referenced.
// Not usually used unless you want to add more logic besides just initializing variables.
fileAccess = new FlightFileAccess();
}
private final String path;
public final int id;
public Dataflights(String path) {
this.path = path;
this.id = fileAccess.generateId();
}
static class FlightFileAccess {
private volatile int nextId = 0;
synchronized public int generateId() {
return nextId++;
}
}
public static void main(String[] args) {
Dataflights d = new Dataflights("my/path");
System.out.println("Id is: " + d.id);
}
}
There are many ways to handle contention. I recommend Java Concurrency in Practice if you aren't familiar with Java concurrency.
You are on the right track in your FlightFileAccess class. I can't see the details, but you might also want to use the synchronized keyword in the signature of the remove() method to protect the entire function first. Then, once you have things working, use more tightly targeted synchronize {...} blocks to reduce the amount of code that has to be singly threaded.

Related

Why do we use static blocks when we already have static methods? [duplicate]

This question already has answers here:
Static Initializers And Static Methods In Java
(4 answers)
Closed 4 years ago.
Why do we use static blocks when we can use static methods for initializing static variables? What difference does it make? What is the logic to this.
I assume you are referring to static initializer blocks?
static { ... }
Static initializer blocks and static methods are both required because they do different things.
Static initializer blocks are blocks for initializing the class. They are run exactly once, when the class is loaded. They don't return anything, and can't throw a checked exception because there is no way to declare throws.
In fact, a static field with an initializer:
static int a = 0;
Is actually converted to a field declaration and a static initializer block:
static int a;
static {
a = 0;
}
You can assign zero or more static final variables in a static initializer, provided they have not already been assigned.
Static methods can be invoked at any time. They can return a value, and throw checked exceptions. You cannot assign static final variables in a static method (although you can assign non-final static variables).
You are thinking about very 2 different ideas about initialize object. for example:
class A {
static Map<String, String> map;
static {
map = new HashMap<String, String>();
}
public static void initializeMap() {
map = new HashMap<String, String>();
}
public static void insert(String key, String value) {
map.put(key, value);
}
}
If we use static initializer block, the very first time you use any static method (i.e: insert), it will run static block first. And by doing this, you are safe for concurrency control. i.e: there are multiple threads try to call method insert at very beginning, Java will only run initialize block once.
Using static method for initialize such as initializeMap in this case, the advantage is you move the control of when run init to your own program. Maybe your class should not init ASAP but only your program told to do so. Other advantage is you can control the return value, or raise exception if needed (you cannot raise exception in static initializer block).
Note that the static method above is not safe and should not call concurrently. Other word, you should make sure only one thread call that method for initialize map. Otherwise, you must add lock to control multiple thread access.
Some other notes about advantages of using static initializer block:
Handle concurrency access automatically provided by Java.
Some program we don't know exactly where to put static method, so using static initializer is a safe choice.
Some complex initialize cannot be done in one line, so static initializer is the only choice.
You have static blocks to do more complex initialization, like for instance this upload queue where you just want to make sure a directory exists.
static {
File f = new File(getUploadDir());
if(!f.exists()) {
//noinspection ResultOfMethodCallIgnored
f.mkdir();
}
}
You can also use it to set some properties on static objects. Here's an example:
private static final SimpleDateFormat mDateTimeFormat = new
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
static {
mDateTimeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
}

Why do we need a private constructor at all?

This answer says that we can't instantiate more than one object at a time via private constructors. I have modified the code which does just the opposite:
class RunDatabase{
public static void main(String[] args){
Database db = Database.getInstance("hello");//Only one object can be instantiated at a time
System.out.println(db.getName());
Database db1 = Database.getInstance("helloDKVBAKHVBIVHAEFIHB");
System.out.println(db1.getName());
}
}
class Database {
//private static Database singleObject;
private int record;
private String name;
private Database(String n) {
name = n;
record = 0;
}
public static synchronized Database getInstance(String n) {
/*if (singleObject == null) {
Database singleObject = new Database(n);
}
return singleObject;*/
return new Database(n);
}
public void doSomething() {
System.out.println("Hello StackOverflow.");
}
public String getName() {
return name;
}
}
And as expected both the strings are being printed. Did I miss something?
We can't instantiate more than one object at a time via private constructors.
No, we can. A private constructor only avoids instance creation outside the class. Therefore, you are responsible for deciding in which cases a new object should be created.
And as expected both the strings are being printed. Did I miss something?
You are creating a new instance every time the getInstance method is called. But your commented code contains a standard lazy initialization implementation of the singleton pattern. Uncomment these parts to see the difference.
Other singleton implementations you can look over here.
Private constructors are used to stop other classes from creating an object of the "Class" which contains the private constructor.
This is done to provide the singleton pattern where only a single instance of the class is used.
The code that you have mentioned is supposed to create just one instance of the class and use that instance only to perform all the operations of that class. But you have modified the code which violates the singleton design pattern.
Why do we need a private constructor at all?
Basically 3 reasons:
if you don't want the user of the class creates an object directly, and instead use builders or similars,
if you have a class defined for constants only, then you need to seal the class so the JVM don't create instances of the class for you at runtime.
singletons

Reasons for declaring a private static final variable

Why would you declare a static final variable as private for an immutable type?
Could it possibly do any harm to declare them public on any case?
So that nobody can access it from outside and rely on that value, giving you the freedom to change it without risk of side-effect (at least outside of the class where it's declared).
There are serveral reasons...
Privacy
Keep implementation details hidden from the clients, for example constants for internal use only and with no use for clients
Security
Protect your code from maliscious client codes for example:
static class A
{
public final static List<String> list = buildList();
public static List<String> buildList()
{
ArrayList<String> list = new ArrayList<>();
list.addAll(Arrays.asList("A", "B", "C"));
return list;
}
}
static class B
{
public static void main(String[] args)
{
A.list.clear();
System.out.println(A.list);
}
}
You dont want any one to manipulate you internal data.
It's just best OOP practice to keep variables within the proper scope. An example would be a global static final integer for performing a number of calculations within the class. Having it exposed (public) not only could cause problems, but confusion as well.
Say you had a class where you needed to know the value of pi:
public class MyClass {
private static final double PI = 3.14159;
//functions performing calculations with value of PI
}
The value of pi is only needed within MyClass, so leaving it to be exposed makes no sense - all calculations with the variable are done within MyClass. If you need it again to perform a calculation, it should be done within the class holding the value to keep your code organized.
public class GUICommon {
private static final ExecutorService executorServices = Executors.newWorkStealingPool();
public static void useExecutors(Runnable run)
{
executorServices.execute(run);
}
}
I used it on this way.

Why use public and private to static members and method?

I'm learning Java and I just wonder why public and private is used when a method or members is static? When static is used they are class methods and class members and could be used from other classes without creating an object, so is public and private necessary? Some help is preciated to understand. Sorry if this question is too simple for some.
The accessibility of a field or method is orthogonal to the fact that it's static or not.
You could have a static method accessible from the outside, and a static method that must only be used from inside the class itself (by other static or non-static methods). The same goes for fields.
For example:
// not visible from the outside
private static final long MILLISECONDS_IN_A_MINUTE = 1000L * 60 * 60;
public static Date addMinutes(Date d, int amount) {
return addMillis(d, MILLISECONDS_IN_A_MINUTE * amount);
}
// not visible from the outside
private static Date addMillis(Date d, long amount) {
return new Date(d.getTime() + amount);
}
It's not necessary, but there can be static methods and data members for internal use only.
An example for this is if you want an unique id for every instance of the class:
class Foo
{
private static int nextId = 0;
private static int generateId() { return ++nextId; }
private int id;
public Foo()
{
id = generateId();
}
}
As you can see, nextId and generateId() are not needed outside the class, nor should they be used outside the class. The class itself is responsible for generating id's. But you need them to be static (well, you need nextId to be static, but you can also make generateId() static since it doesn't access non-static members).
Whenever an object Foo is created, the static counter is incremented, thus you get different ids for each instance of the class. (this example is not thread-safe)
Suppose you have a static public method and this method must access to a private attribute. This private attribute must be static too. There's one reason why private static exists.
Example :
public class Test {
private static int myattr = 0;
public static void foo() {
myattr = 2;
}
}
Above, myattr must be a static attribute in order to use it in the foo() method.
Yes it is needed.
If you have a Static Method and want to use a private variables in that method, then you need to declare it static too.
Or you want the static variables not be visible to other packages, then don't declare it public.
From what I remember, it's not really needed. But public means, basically in any programming language, that it can be used by outside files. With private it can only be used within that file, and static means you cannot change the value of said reference. Whether these be functions, or variables, the same rules apply. I might be off. Haven't done Java in about a year and a half.
The ways you can incorporate these types is up to you. After all, a program is only as diverse as it's user. ^_^
Public and private keywoards have to do with visibility: which members do you want to accessible to other classes and which should be hidden or encapsulated.
Static members relate to the class as a whole, while non-static members operate on object instances.
I'm learning Java and I just wonder why public and private is used when a method or members is static?
I believe your question is due to a common misconception that the access modifiers are for instances, but they're not!
Two different instances can access each others private members if they are of the same class.
In other words, the access modifiers works on class level. Since also static members belong to some class, it makes sense to have access modifiers also on them.
A static method (or variable) that should only be used by code in the same class (as in the example by JB Nizet) should be private, while a static method or variable that may be used by code in any class should be public.
When the static is used with methods it doesn't only mean that it should be used by the members of other classes.
The case when we access the static methods of a class is one when
the class (which contains the method) cannot be instantiated i.e. no objects can be created of that class.
There may be situations when two different classes may have static methods with same name. In that case you want to use the method of the same class not the method of other class.

Global variables in Java

How do you define Global variables in Java ?
To define Global Variable you can make use of static Keyword
public class Example {
public static int a;
public static int b;
}
now you can access a and b from anywhere
by calling
Example.a;
Example.b;
You don't. That's by design. You shouldn't do it even if you could.
That being said you could create a set of public static members in a class named Globals.
public class Globals {
public static int globalInt = 0;
///
}
but you really shouldn't :). Seriously .. don't do it.
Another way is to create an interface like this:
public interface GlobalConstants
{
String name = "Chilly Billy";
String address = "10 Chicken head Lane";
}
Any class that needs to use them only has to implement the interface:
public class GlobalImpl implements GlobalConstants
{
public GlobalImpl()
{
System.out.println(name);
}
}
You are better off using dependency injection:
public class Globals {
public int a;
public int b;
}
public class UsesGlobals {
private final Globals globals;
public UsesGlobals(Globals globals) {
this.globals = globals;
}
}
Lots of good answers, but I want to give this example as it's considered the more proper way to access variables of a class by another class: using getters and setters.
The reason why you use getters and setters this way instead of just making the variable public is as follows. Lets say your var is going to be a global parameter that you NEVER want someone to change during the execution of your program (in the case when you are developing code with a team), something like maybe the URL for a website. In theory this could change and may be used many times in your program, so you want to use a global var to be able to update it all at once. But you do not want someone else to go in and change this var (possibly without realizing how important it is). In that case you simply do not include a setter method, and only include the getter method.
public class Global{
private static int var = 5;
public static int getVar(){
return Global.var;
}
//If you do not want to change the var ever then do not include this
public static void setVar(int var){
Global.var = var;
}
}
Truly speaking there is not a concept of "GLOBAL" in a java OO program
Nevertheless there is some truth behind your question because there will be some cases where you want to run a method at any part of the program.
For example---random() method in Phrase-O-Matic app;it is a method should be callable from anywhere of a program.
So in order to satisfy the things like Above "We need to have Global-like variables and methods"
TO DECLARE A VARIABLE AS GLOBAL.
1.Mark the variable as public static final While declaring.
TO DECLARE A METHOD AS GLOBAL.
1. Mark the method as public static While declaring.
Because I declared global variables and method as static you can call them anywhere you wish by simply with the help of following code
ClassName.X
NOTE: X can be either method name or variable name as per the requirement and ClassName is the name of the class in which you declared them.
There is no global variable in Java
Nevertheless, what we do have is a static keyword and that is all we need.
Nothing exists outside of class in Java. The static keyword represents a class variable that, contrary to instance variable, only has one copy and that transcends across all the instances of that class created, which means that its value can be changed and accessed across all instances at any point.
If you need a global variable which can be accessed beyond scopes, then this is the variable that you need, but its scope exists only where the class is, and that will be all.
Nothing should be global, except for constants.
public class MyMainClass {
public final static boolean DEBUGMODE=true;
}
Put this within your main class. In other .java files, use it through:
if(MyMainClass.DEBUGMODE) System.out.println("Some debugging info");
Make sure when you move your code off the cutting room floor and into release you remove or comment out this functionality.
If you have a workhorse method, like a randomizer, I suggest creating a "Toolbox" package! All coders should have one, then whenever you want to use it in a .java, just import it!
There is no such thing as a truly global variable in Java. Every static variable must belong to some class (like System.out), but when you have decided which class it will go in, you can refer to it from everywhere loaded by the same classloader.
Note that static variables should always be protected when updating to avoid race conditions.
Understanding the problem
I consider the qualification of global variable as a variable that could be accessed and changed anywhere in the code without caring about static/instance call or passing any reference from one class to another.
Usually if you have class A
public class A {
private int myVar;
public A(int myVar) {
this.myVar = myVar;
}
public int getMyVar() {
return myVar;
}
public void setMyVar(int mewVar) {
this.myVar = newVar;
}
}
and want to access and update myvar in a class B,
public class B{
private A a;
public void passA(A a){
this.a = a;
}
public void changeMyVar(int newVar){
a.setMyvar(newVar);
}
}
you will need to have a reference of an instance of the class A and update the value in the class B like this:
int initialValue = 2;
int newValue = 3;
A a = new A(initialValue);
B b = new B();
b.passA(a);
b.changeMyVar(newValue);
assertEquals(a.getMyVar(),newValue); // true
Solution
So my solution to this, (even if i'm not sure if it's a good practice), is to use a singleton:
public class Globals {
private static Globals globalsInstance = new Globals();
public static Globals getInstance() {
return globalsInstance;
}
private int myVar = 2;
private Globals() {
}
public int getMyVar() {
return myVar;
}
public void setMyVar(int myVar) {
this.myVar = myVar;
}
}
Now you can get the Global unique instance anywhere with:
Globals globals = Globals.getInstance();
// and read and write to myVar with the getter and setter like
int myVar = globals.getMyVar();
global.setMyVar(3);
public class GlobalClass {
public static int x = 37;
public static String s = "aaa";
}
This way you can access them with GlobalClass.x and GlobalClass.s
If you need to update global property, a simple getter/setter wrapper class can be used as global variable. A typical example is shown below.
public class GlobalHolder {
private static final GlobalHolder INSTANCE = new GlobalHolder();
private volatile int globalProperty;
public static GlobalHolder getInstance() {
return INSTANCE;
}
public int getGlobalProperty() {
return globalProperty;
}
public void setGlobalProperty(int globalProperty) {
this.globalProperty = globalProperty;
}
public static void main(String[] args) {
GlobalHolder.getInstance().setGlobalProperty(10);
System.out.println(GlobalHolder.getInstance().getGlobalProperty());
}
}
public class GlobalImpl {
public static int global = 5;
}
you can call anywhere you want:
GlobalImpl.global // 5
Creating an independent file, eg. Example.java to use the 1st solution, is just fine. You can do that also within the app, if e.g. the global variables are special to your current app, etc.:
Create a class at the beginning and declare your variables in there:
class Globals {
static int month_number;
static String month_name;
}
You can then access these variables -- using them as 'Globals.month_number', etc. -- from averywhere in your app.
very simple:
class UseOfGlobal
{
private static int a;
private static int b;
}
but it is always good to have local variables defined inside method blocks where ever possible.
As you probably guess from the answer there is no global variables in Java and the only thing you can do is to create a class with static members:
public class Global {
public static int a;
}
You can use it with Global.a elsewhere. However if you use Java 1.5 or better you can use the import static magic to make it look even more as a real global variable:
import static test.Global.*;
public class UseGlobal {
public void foo() {
int i = a;
}
}
And voilà!
Now this is far from a best practice so as you can see in the commercials: don't do this at home
There are no global variables in Java, but there are global classes with public fields. You can use static import feature of java 5 to make it look almost like global variables.
Generally Global variable (I assume you are comparing it with C,Cpp) define as public static final
like
class GlobalConstant{
public static final String CODE = "cd";
}
ENUMs are also useful in such scenario :
For Example Calendar.JANUARY)
To allow an unqualified access to static members of another class, you can also do a static import:
import static my.package.GlobalConstants;
Now, instead of print(GlobalConstants.MY_PASSWORD);
you can use the Constant directly: print(MY_PASSWORD);
See What does the "static" modifier after "import" mean? to decide about.
And consider the answer of Evan Lévesque about interfaces to carry the Constants.
// Get the access of global while retaining priveleges.
// You can access variables in one class from another, with provisions.
// The primitive must be protected or no modifier (seen in example).
// the first class
public class farm{
int eggs; // an integer to be set by constructor
fox afox; // declaration of a fox object
// the constructor inits
farm(){
eggs = 4;
afox = new fox(); // an instance of a fox object
// show count of eggs before the fox arrives
System.out.println("Count of eggs before: " + eggs);
// call class fox, afox method, pass myFarm as a reference
afox.stealEgg(this);
// show the farm class, myFarm, primitive value
System.out.println("Count of eggs after : " + eggs);
} // end constructor
public static void main(String[] args){
// instance of a farm class object
farm myFarm = new farm();
}; // end main
} // end class
// the second class
public class fox{
// theFarm is the myFarm object instance
// any public, protected, or "no modifier" variable is accessible
void stealEgg(farm theFarm){ --theFarm.eggs; }
} // end class
Going by the concept, global variables, also known as instance variable are the class level variables,i.e., they are defined inside a class but outside methods. In order to make them available completely and use them directly provide the static keyword.
So if i am writing a program for simple arithmetical operation and it requires a number pair then two instance variables are defined as such:
public class Add {
static int a;
static int b;
static int c;
public static void main(String arg[]) {
c=sum();
System.out.println("Sum is: "+c);
}
static int sum() {
a=20;
b=30;
return a+b;
}
}
Output: Sum is: 50
Moreover using static keyword prior to the instance variables enable us not to specify datatypes for same variables again and again. Just write the variable directly.
In general, Java doesn't have any global variables. Other than local variables, all variables comes under the scope of any class defined in the program.
We can have static variables to have the scope of global variables.
without static this is possible too:
class Main {
String globalVar = "Global Value";
class Class1 {
Class1() {
System.out.println("Class1: "+globalVar);
globalVar += " - changed";
} }
class Class2 {
Class2() {
System.out.println("Class2: "+globalVar);
} }
public static void main(String[] args) {
Main m = new Main();
m.mainCode();
}
void mainCode() {
Class1 o1 = new Class1();
Class2 o2 = new Class2();
}
}
/*
Output:
Class1: Global Value
Class2: Global Value - changed
*/
Object-Oriented Programming is built with the understanding that the scope of variables is closely exclusive to the class object that encapsulates those variables.
The problem with creating "global variables" is that it's not industry standard for Java. It's not industry standard because it allows multiple classes to manipulate data asyncronized, if you're running a multi-threaded application, this gets a little more complicated and dangerous in terms of thread-safety. There are various other reasons why using global variables are ineffective, but if you want to avoid that, I suggest you resort to Aspect-Oriented Programming.
Aspect-Oriented Programming negates this problem by putting the parent class in charge of the scope through something called "advices", which adds additional behavior to the code without actually modifying it. It offers solutions to cross-cutting concerns, or global variable usage.
Spring is a Java framework that utilizes AOP, and while it is traditionally used for web-applications, the core application can be used universally throughout the Java framework (8.0 included). This might be a direction you want to explore more.
To define Global Variable you can make use of static Keyword
public final class Tools {
public static int a;
public static int b;
}
now you can access a and b from anywhere by calling
Tools.a;
Tools.b;
Yoy are right...specially in J2ME...
You can avoid NullPointerException by putting inside your MidLet constructor
(proggy initialization) this line of code:
new Tools();
This ensures that Tools will be allocated before any instruction
that uses it.
That's it!

Categories