Consider the following code:
public class Foo {
private static final Object LOCK = new Object();
private Object _lockRef1 = LOCK;
private Object _lockRef2 = LOCK;
private int _indx = 0;
public void dec() {
synchronized(_lockRef1) {
_indx--;
}
}
public void inc() {
synchronized(_lockRef2) {
_indx++;
}
}
}
Is call to methods dec() and inc() threadsafe? On the one hand these methods are synchronized on two different instances _lockRef1 and _lockRef2. On the other hand, these instances "point" on the same object LOCK...
They're not "synchronized on two different instances" - just because you use two different variables doesn't mean there are two different instances. You've got several variables each of which will have the same value - a reference to the single instance of java.lang.Object.
So yes, this is thread-safe. Of course you shouldn't write code like this in terms of readability, but assuming you're just trying to understand what happens, it's fine.
Related
I know that final instance-variables are published safely to all threads, after the constructor is finished. However, I wonder whether this is still safe, if the final instance-variable contains a reference to an object that contains a non-final instance-variable. This secondary, non-final instance-variable is never changed after the constructor is done. Consider the following example:
public class NonFinalImmutable {
private Iterable<String> list = Collections.unmodifiableList(Arrays
.asList("foo", "bar", "foobar"));
public Iterable<String> getList() {
return list;
}
}
public class FinalImmutable {
private final NonFinalImmutable reference;
private final String[] array;
public FinalImmutable(NonFinalImmutable reference,
String... arrayEntries) {
this.reference = reference;
this.array = arrayEntries;
}
public NonFinalImmutable getReference() {
return reference;
}
public String[] getArray() {
return array;
}
}
private void execute() {
new Thread() {
#Override
public void run() {
useLater(construct());
}
}.start();
}
private FinalImmutable construct() {
return new FinalImmutable(new NonFinalImmutable(), "asdf", "jklö");
}
private void useLater(FinalImmutable finalImmutable) {
new Thread() {
#Override
public void run() {
for (String s : finalImmutable.getReference().getList()) {
System.out.println(s);
}
System.out.println();
for (String s : finalImmutable.getArray()) {
System.out.println(s);
}
}
}.start();
}
Is it safe to use the contents of the instance-variables FinalImmutable.reference and FinalImmutable.array in another thread even though they contain non-final instance-variables?
Yes, there is a freeze-action which occurs when assigning final fields. You should read Aleksey Shipilëv's blog it's really useful. He discusses the freeze action semantics in a 2014 blog entry
And here is how it is formally specified. Notice that w may not be the write of final field, and r2 is not the read of the final field. What really matters is that the subchain containing freeze action F, some action a, and r1 which reads the final field — all together make r2 observe w.
Notice two new orders, dereference order, and memory
In the blog he proves that a write of final field happens before some action which in turn happens before a subsequent non-final field read r2.
Also in your example, since you first construct the a non-shared NonFinalImmutable the final assignment should freeze the writes occurred prior. If the NonFinalImmutable was accessible outside, all bets are off.
Let's say I have a class called Object and a thread called ObjectCreator that manages the creation of an Object. For the sake of simplicity, Object has attributes: objectNumber and objectName.
If I were to create an instance of Object called instance, it would be held by ObjectCreator. Now let's say I needed another thread (let's call it ObjectChanger) to be able to see and manipulate instance; does it make sense to turn instance into a static Object?
I've managed to see results by making instance static so now I can do something like:
ObjectCreator.instance.getName();
Where getName() is a method of Object. From what I've read from answers to similar questions, static things are evil and there's always workarounds. One suggestion I've read is to pass instance to ObjectChanger as an argument for its constructor but what if instance wasn't created yet at the time I need to create an ObjectChanger?
Perhaps this question is more about OOP concepts than multi-threading or it may be a duplicate so forgive me but I'm quite lost here.
EDIT: To address frankie's and Jim's suggestions, here are some code snippets:
Object:
class Object
{
private String objectName = "Something";
private int objectNumber = 1;
public synchronized void changeNumber(int newNumber)
{
objectNumber = newNumber;
}
}
ObjectCreator:
class ObjectCreator extends Thread
{
static Object instance;
public ObjectCreator (Object something)
{
instance = something;
}
static void createObject()
{
...
}
static Object getObject()
{
return instance;
}
}
ObjectChanger:
public class ObjectChanger extends Thread
{
private Object currentInstance = null;
private int instanceNumber = null;
public void run()
{
currentInstance = ObjectCreator.getObject(); //If I were to make getObject() non-static, this line churns up an error
instanceNumber = currentInstance.getObjectNumber();
currentInstance.changeNumber(2); //valid?
}
}
If you want a thread to obtain access to an object not created within it, you must ensure that said thread has a path of references which it can follow, leading to the new object.
Consider the following code, with no threads involved.
class MyObject { /* ... */ }
interface MyObjectProvider {
MyObject getMyObject();
}
class Creator implements MyObjectProvider {
private MyObject obj;
/* ... */
#Override
public MyObject getMyObject() {
return obj;
}
/** Invoked at some point in time. */
void createMyObject() {
obj = new MyObject();
}
}
class Consumer {
private MyObjectProvider provider;
Consumer(MyObjectProvider mop) {
provider = mop;
}
void consume() {
// At some point in time...
MyObject o = provider.getMyObject();
}
}
Example of a program:
public static void main(String[] args) {
Creator creator = new Creator();
Consumer consumer = new Consumer(creator);
creator.createMyObject();
consumer.consume();
}
When you add threads to the mix, some code has to change, but the struture is the same.
The idea is to run the Creator in a thread, and the Consumer in another, as you've pointed out.
So, in short, these are the things you should be looking into:
Concurrency control: look into data races, synchronized, mutual exclusion, and their friends. Start here.
wait and notify, if the Consumer should wait for MyObject to be created. Look here.
When you have a nice grasp on these concepts, you may look into the volatile keyword (watch out for its pitfalls), and the java.util.concurrent package which provides better concurrency primitives, concurrent collections, and atomic variables.
You can put your objects in a list structure like Vector and store them in the ObjectCreator. Add a getter method to ObjectCreator which will accept an index of the object to be received.
This is just a skeleton showing the basic structure. Error handling is left as an exercise :-)
public class MyObject { ... }
...
public class MyObjectCreator {
private Map<String,MyObject> createdObjects = new HashMap<>();
public MyObject makeNewObject(int objNum, String objName)
{
MyObject o = new MyObject(objNum, objName);
this.createdObjects.put(objName,o);
}
public MyObject getObject(String objName)
{
return this.createdObjects.get(objName);
}
}
...
public class MyProgram {
public static void main(String[] args)
{
MyObjectCreator oc = new MyObjectCreator();
MyObject mo = oc.makeNewObject(10,"aNewObject");
...
MyObject o = oc.get("aNewObject");
...
If you only want to change the values of the fields of your class, you should just pass the object into your newly created thread. Then there is really no need to keep a static reference around in a holder class.
But as commented already, we need a bit more information to get to what you want to do with your object and thread.
Why cant you just make an getter in the ObjectCreator class that retrieves said Object?
ex: ObjectCreater.getMyObject()
EDIT:
I think you're looking for something like this if Im not mistaken:
public class ObjectCreator{
ArrayList<Object> children;
public ObjectCreator(){
children = new ArrayList<Object>();
}
//returns back index in children array (for accessing from other threads)
public int createObject( whatever params here ){
Object o = new Object( params );
children.add(o);
return children.size()-1;
}
}
since I dont know much about the problem you're trying to solve, Im not sure if it has to be thread safe, if you want these objects mapped, or accessed differently, but Im confused where all the confusion about static is coming...
In Java, I have created a singleton class as follows:
public class Singleton
{
private Singleton() { print("Singleton Constructor"); }
private static Singleton pointer = new Singleton();//static here so only one object
public static Singleton makeSingleton()
{
return pointer;
}
public static void main (String args[])
{
Singleton nuReference = Singleton.makeSingleton();
if(nuReference == pointer)
{
print("Both are references for same object.");
}
}
}
Here, only the reference to an already-created object of Singleton class is being returned. How can I create a class so that only, say, four objects of that class are allowed to be created? Can I use this Singleton class for that or do I have to make it from scratch?
Oh, and print() is my custom method here. Works the same as System.out.println(), just with fewer keystrokes :)
That should work:
public class Singleton
{
private Singleton()
{
print("Constructor");
}
private static Singleton instances[] = new Singleton[4];
private static Boolean initiated = false;
public static Singleton getInstance(int index)
{
tryInitiate();
if(instances[index] == null)
{
instances[index] = new Singleton();
}
return instances[index];
}
private static Boolean tryInitiate()
{
if(initiated) return false;
for (int i = 0; i < instances.length; i++)
{
instances[i] == null;
}
initiated = true;
return true;
}
}
Instead of initiating the objects with "null" you could also instantiate the objects during the initiation. But this way only the needed objects are instantiated.
Add a static int count = numyouwant; to your code, every time the static creation method is called, reduce the count by 1. and more importantly, check whether count is 0 before call the private constructor in the creation method~
Singletons, by definition, only have a single instance of itself. What you're suggesting sounds like you would make better use of a Factory-type paradigm, along with a counter/limiter (built into the class).
Make a Factory class that contains a counter (or a list to store created objects, if you prefer) and a createObject method. In the method, do your logic for determining whether there are too many objects, and therefore you may limit creation of the objects.
Here's an example of a Factory with a max limit on created objects. The object in question is an inner class for simplicity.
public class Factory {
private final int maxObj = 4;
public class MyObject {
MyObject() { print("Constructor"); }
}
private List<MyObject> objects = new List<Object>();
// Returns new MyObject if total MyObject
// count is under maxObj, null otherwise
public MyObject makeObject() {
if (objects.length() >= maxObj)
return null;
MyObject obj = new MyObject();
objects.add(obj);
return obj;
}
}
create a variable x
increase its value every time when makeSingleton is called
if x<4 then return pointer
else return null
Create a field of List<Singleton> mySingletons; and a field int singletonCounter=0;
in makeSingleton() method add 1 to counter if it is equal to 4 return null or return a singleton of 4.If counter is less than 4 then create a singleton.
my question is that how can i create a class so that say only 4 objects of that class are allowed to be created. any help ?
can i use this Singleton class for that or do i have to make it from scratch ?
I believe you want to keep a pool of objects of a class . You can't do it through a Singleton class , which by definition should return the only instance it has.
Suggested reads:
Object Pool in Java
.
Build your own ObjectPool
You could add a Queue of 4 instances of the same object, and manage the queue/dequeue operations.
Beware: Sounds you should apply thread-safety for those operations.
I created one with Thread Safty
import java.util.ArrayList;
import java.util.List;
public class SingletonLimit{
private List<SingletonLimit> inst_Obj= new ArrayList<>();
private static final int maxLimit=4;
private SingletonLimit(){
}
public SingletonLimit getInstance(){
if(inst_Obj.size()>=maxLimit)
return null;
SingletonLimit singleLimit=null;
synchronized(SingletonLimit.class){
singleLimit= new SingletonLimit();
inst_Obj.add(singleLimit);
}
return singleLimit;
}
}
I have thread safe double checked Singleton class that holds a LinkedList with get/set/size methods in the Singleton class. Then I have simple pool class that is using this Singleton class to manage pool of objects.
My question is how can I defend the methods of get/set both in the singleton and the pool class without using sync methods. Here's my code
public class SingletonDoubleCheckedLockingPattern {
private static SingletonDoubleCheckedLockingPattern s = new SingletonDoubleCheckedLockingPattern();
private LinkedList<Object> linkedList;
public int GetListObjectCount() {
return linkedList.size();
}
public Object GetObjectFromList() {
return linkedList.poll();
}
public void SetObjectFromList(Object ee) {
linkedList.add(ee);
}
private SingletonDoubleCheckedLockingPattern() {
linkedList = new LinkedList<Object>();
}
/**
* SingletonHolder is loaded on the first execution of
* Singleton.getInstance() or the first access to SingletonHolder.INSTANCE,
* not before.
*/
private static class SingletonHolder {
public static final SingletonDoubleCheckedLockingPattern INSTANCE = new SingletonDoubleCheckedLockingPattern();
}
public static SingletonDoubleCheckedLockingPattern getInstance() {
return SingletonHolder.INSTANCE;
}
// avoid cloning
public final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
public class SingletonObjectPool {
private int maxlistValue = 10;
public Object GetObject()
{
int listCount = SingletonDoubleCheckedLockingPattern.getInstance().GetListObjectCount();
if(listCount > 0)
{
return SingletonDoubleCheckedLockingPattern.getInstance().GetObjectFromList();
}
return null;
}
public void SetObject()
{
int listCount = SingletonDoubleCheckedLockingPattern.getInstance().GetListObjectCount();
if(listCount < maxlistValue)
{
SingletonDoubleCheckedLockingPattern.getInstance().SetObjectFromList(new Object());
}
}
}
You could use a BlockingQueue which is thread safe. You shouldn't need to check whether a collection is empty before attempting to remove an element, the collection has a method to do this.
To simplify your code and make it thread safe you can do.
public class SingletonObjectPool {
private static final int maxlistValue = 10;
private static final BlockingQueue queue
= new ArrayBlockingQueue(maxListValue);
public static Object getObject() {
return queue.poll();
}
public static void addObjectAsRequired() {
queue.offer(new Object());
}
}
The only way I can think that you can possibly call methods such as GetListObjectCount without using synchronized, is if the list itself is thread-safe and will behave sensibly when this method is called in the face of concurrent modifications.
In that case, there won't be any other problems, as the reference to the list itself never changes. You may want to declare it as final to make this abundantly clear, and to have the compiler warn anyone who tries to reassign the list. (If this were a requirement, the reference would need to be volatile at the very least, but it opens up lots of other questions in the correctness of multiple operations of your class).
The bottom line is that "thread safety" is not a simple, binary concept. You can't just say a particular class and/or method is thread-safe; rather, it's about what combinations of methods you can call with useful and correct semantics.
I was asking this question about controlling a thread that was reading from a blocking queue. Although it wasn't the solution I chose to go with, several people suggested that a special "poison pill" or "sentinel" value be added to the queue to shut it down like so:
public class MyThread extends Thread{
private static final Foo STOP = new Foo();
private BlockingQueue<Foo> blockingQueue = new LinkedBlockingQueue<Foo>();
public void run(){
try{
Foo f = blockingQueue.take();
while(f != STOP){
doSomethingWith(f);
f = blockingQueue.take();
}
}
catch(InterruptedException e){
}
}
public void addToQueue(Foo f) throws InterruptedException{
blockingQueue.put(f);
}
public void stop() throws InterruptedException{
blockingQueue.put(STOP);
}
}
While I like this approach, I decided not to use it because I wasn't sure what value to use for the STOP field. In some situations it's obvious - for instance, if you know you're inserting positive integers, negative numbers could be used as control values - but Foo is a fairly complex class. It's immutable and hence has a constructor that takes several arguments. To add a no-argument constructor would mean leaving several fields uninitialised or null, which would cause methods to break if they were used elsewhere - Foo is not just used with MyThread. Similarly, putting dummy values into the main constructor would just pass this problem on as several of the fields and constructor parameters are themselves significant objects.
Am I simply programming over-defensively? Should I worry about adding no-argument constructors to a class, even if there are no setters to make the object usable (just assume other programmers will be sensible enough to not use that constructor)? Is the design of Foo broken if it can't have a no-argument constructor or at least a non-value - would it be better to put if(someField == null){throw new RuntimeException();} checks in all methods?
I don't really see what the advantage of this design is versus a simple boolean variable to indicate the loop should stop.
But if you really want to go with this design, I would suggest making a private no-arg constructor, and making a static STOP Foo. Like this.
public class Foo {
public static final Foo STOP = new Foo();
... fields
private Foo(){}
public Foo(...){
...
}
...
}
public class MyThread extends Thread{
private static final Foo STOP = new Foo();
private BlockingQueue<Foo> blockingQueue = new LinkedBlockingQueue<Foo>();
public void run(){
try{
Foo f = blockingQueue.take();
while(f != STOP){
doSomethingWith(f);
f = blockingQueue.take();
}
}
catch(InterruptedException e){
}
}
public void addToQueue(Foo f) throws InterruptedException{
blockingQueue.put(f);
}
public void stop() throws InterruptedException{
blockingQueue.put(Foo.STOP);
}
}
This has the advantage that you're still not exposing an invalid constructor.
The disadvantage is that the Foo class knows that in some cases it's used as a 'poison pill', which might not be what it's for. Another disadvantage is that The STOP object might be inconsistent. You could make an anonymous subclass from it do disable the methods with UnsupportedOperationException or something.
I think you're right about not using empty constructors. If Foo is such an complex class, it doesn't seem logical to use a complete object for that.
If adding a null is possible. That seems a nice way to go.
Another way could also be to implement an interface. IBlockableQueueObject? This could be implemented by the foo object and by the STOP sign. Only thing is that you have to cast the interface back to the Foo if it is not a STOP.
another option would be to wrap Foo in a generic wrapper such as this:
public class Wrapped<T> {
private final T value;
public Wrapped(T value) {
this.value = value;
}
public T get() { return value; }
}
which you can then use to pass a null value as a poison pill to a BlockingQueue<Wrapped<Foo>>.
You should worry about having no-argument constructors that don't result in usable instances.
The design of Foo sounds fine - I would generally assume that I'm not allowed to pass in null into a constructor unless the documentation specifically allows me to. Especially with an immutable class.