I have a class Manager that is going to be accessed by multiple threads at the same time, I want to know if I did it the right way ?
also I think I need RemoveFoo to be atomic, but I'm not sure
public class Manager
{
private ConcurrentHashMap<String, Foo> foos;
//init in constructor
public RemoveFoo(String name)
{
Foo foo = foos.Get(name);
foo.RemoveAll();
foos.Remove(name);
}
public AddFoo(Foo foo)
{...}
}
public class Foo
{
private Map<String,Bar> bars;
//intialize it in constructor
//same for RemoveBar
public void AddBar(Bar bar)
{
synchronized(this)
{
bars.put(bar.id, bar);
}
}
public void RemoveAll()
{
synchronized(this)
{
//some before removall logic for each one
bars.remove(bar.id, bar);
}
}
}
public class Bar
{}
You do not need synchronised methods as you are using a ConcurrentHashMap, however be aware that Foo foo = foos.Get(name) could return null as another thread could already have removed the entry from the map.
Members can be declared as Map<String, Foo> foos, but must be initialsed as foos = new ConcurrentHashMap<String, Foo>;
RemoveFoo could be problematic. I suggest to use:
Foo foo = foos.remove (name);
if (foo != null) foo.removeAll();
instead. This makes sure that the map doesn't change between get() and remove().
In Foo, it's enough to synchronize on bars instead of the whole instance. But that's just a minor optimization.
Declare RemoveFoo(String) as synchronized:
public synchronized void RemoveFoo(String name) {
…
}
Also, be advised of the following:
method names should be lower case, e.g. removeFoo instead of RemoveFoo. This is not C#. :)
Every method needs a return type: public removeFoo() is not a valid method declaration, it needs to be public void removeFoo().
If you use a concurrentHashMap in Foo like
private Map<String,Bar> bars = new ConcurrentHashMap<String, Bar>();
maybe you can do away with the synchronization in Foo as well.
I am not sure what you are going to do on Foo and Bar, but it looks like a pattern of deallocation.
If they are not referenced by others, just call foos.Remove(name); and let GC engine handle the deallocation.
Related
I have listenner method which handle messages implemented by Spring cloud stream like this:
#StreamListener(value = MyInterface.INPUT)
public void handleMsg(#Payload Foo foo) {
// if (concurrentHashMap.containsKey(foo.getId())) concurrentHashMap.remove(foo.getId());
}
here is my second method, which should be blocked by previous:
public Foo getFoo(long fooId) {
// here I need block method with some mechanism until handleMsg remove received object from map and return this foo from there
return fooFromStream;
}
My goal is call getFoo method from service class like this:
// some logic
Foo foo = service.getFoo(fooId);
// some logic which required received foo;
I had idea wrap Foo in getFoo method into AsyncResult and next call method get on Future result of that which cause block, but I have no idea how to pass foo from stream into method getFoo
Use case should be this:
I call method getFoo which send foo into message broker and register foo in map, and do some logic, and next when command is done I receive message in StreamListenner, remove foo from map, and next I need return that foo from method getFoo.
Can you tell me how to do that or what is the best practice to solve it? Thank you in advice.
It's not entirely clear what you are trying to do but a Map<Long, BlockingQueue<Foo> will allow you to block on take (or, poll with a timeout is probably better) until the listener offers the Foo; then remove the map entry.
Bear in mind that once the Foo is put in the queue, the record will be ack'd and, if the server crashes, it will be lost.
You could use a concurrent Map of Long and Blocking queues blocking queue for that:
ConcurrentMap<Long, BlockingQueue<Foo>> fooMap = new ConcurrentHashMap<>();
...
private BlockingQueue<Foo> getFooQueue(long fooId) {
return fooMap.computeIfAbsent(fooId, l -> new ArrayBlockingQueue<>(1));
}
...
#StreamListener(value = MyInterface.INPUT)
public void handleMsg(#Payload Foo foo) {
BlockingQueue<Foo> fq = getFooQueue(foo.getId());
synchronized(fq) {
fq.clear();
fq.add(foo);
}
}
...
public Foo getFoo(long fooId) throws InterruptedException {
BlockingQueue<Foo> fq = getFooQueue(fooId);
synchronized(fq) {
return fq.take();
}
}
These 2 synchronized blocks are only needed if it may be possible that your handleMsg can be called multiple times when a currently available foo should be overridden with the new foo.
Suppose I have a file like this:
import javax.swing.JPanel;
import java.awt.event.MouseAdapter;
public class Foo extends JPanel
{
private int m;
private int n;
private int o;
public Foo()
{
this.addMouseListener(new Bar());
}
class Bar extends MouseAdapter
{
// ...
// methods here access and modify values of the private
// instance variables.
// ...
}
}
Obviously I can add simple accessors and mutators to Foo but that gets tedious fast and completely breaks encapsulation. How can I refactor this inner class while keeping damage to encapsulation to a minimum?
If these classes seem too big, then you should split them. The first step in splitting them would be to stop relying on private instance variables of the outer class. You could, as you say, add public getters and setters, but better would be to have Foo implement a public interface of Bar, and have Bar simply talk to that interface. And initialize each Bar with self.
public class Bar extends MouseAdapter {
public interface Caller {
void thingClicked();
...
}
}
public class Foo extends JPanel implements Bar.Caller {
...
}
So where now in Bar you have something like:
public void mouseUp() {
m = m + 1;
n = 0
}
you would now have
public void mouseUp() {
caller.thingClicked();
}
and, in Foo:
public void thingClicked() {
m = m + 1;
n = 0
}
It's hard to make this clear without more specifics, but basically your outer class is responding to messages, and the mouse listener is only responsible for delivering those messages, not for what happens in response to them. In the examples above it looks like this is more code than what you already have, but I suspect you'll find that slicing it out in this way ultimately leads to less code - and certainly code which is easier to test and reuse.
One approach is to put the class bar in a new file and inject everything you need there into the constructor. You'd need to change your primitive types like int into objects like Integer. Then you can create a Builder class that steers the construction of Foo and Bar. Let's assume for simplicity you need the same instance of Baz in all of your Foo and Bar instances:
class Builder {
// objects that both classes need are stored as member variables
// if you need multiple instances of baz you can also store a BazBuilder here
private Baz baz;
public Builder(Baz baz) {
this.baz=baz;
}
public Foo buildFoo() {
Foo foo = new Foo(baz);
return foo;
}
public Bar buildBar() {
Bar bar = new Bar(baz);
return bar;
}
}
This is only a minimalistic example but it's easy to extend. Builder#buildFoo() could take arguments that are needed in the constructor of Foo and likewise for Bar.
EDIT
Small example of what it might look like with a BazBuilder:
class BazBuilder {
Baz build(int value) {
return new Baz(value);
}
}
And in Builder you can use it like so:
class Builder {
private BazBuilder bazBuilder;
public Build(BazBuilder bazBuilder) {
this.bazBuilder = bazBuilder;
}
public Foo buildFoo() {
Baz baz = bazBuilder.build(5);
Bar bar = new Bar(baz);
Foo foo = new Foo(baz);
foo.add(bar);
return foo;
}
}
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...
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.
I'm working on some classes that get part of their configuration from global variables, e.g.
class MyClass {
public void MyClass(Hashtable<String, String> params) {
this.foo = GlobalClass.GLOBALVAR.get("foo");
this.bar = GlobalClass.GLOBALVAR.get("bar");
this.params = params;
}
}
This is bad for a couple of reasons, GLOBALVAR talks to a database to get some of the variables and this makes it really hard to make unit tests. The other problem is that I have many (dozens) of classes that inherit from MyClass, so I can't easily change the constructor signature.
My current solution is to create an additional default constructor and setter methods for params, foo and bar.
class MyClass {
// Other code still here for backwards compatibility.
public void MyClass() {
// Do nothing much.
}
public void setParams(Hashtable<String, String> params) {
this.params = params;
}
public void setFoo(Foo foo) {
this.foo = foo;
}
public void setBar(Bar bar) {
this.bar = bar;
}
}
Any ideas on a good way to refactor this, besides the way I did it? My other thought would be to use a factory method, but I'm afraid I'll run into polymorphic substitution problems.
I think I would start by doing the following. It let's your existing code work without modification, and allows you to add new constructors to the subclasses as you can. Once all of the subclasses have the new constructor, and all of the calls to the old constructors are gone, you can get rid of the GlobalClass and the constructors that use it. You can also then, hopefully, work on cleaning up the GLOBALVAR (the Car class in my code).
import java.util.Hashtable;
class MyClass
{
private final Foo foo;
private final Bar bar;
private final Hashtable<String, String> params;
public MyClass(final Hashtable<String, String> params)
{
this(params, GlobalClass.GLOBALVAR);
}
// added constructor
public MyClass(final Hashtable<String, String> params,
final FooBar fooBar)
{
this.foo = fooBar.getFoo();
this.bar = fooBar.getBar();
this.params = params;
}
}
class MySubClass
extends MyClass
{
public MySubClass(final Hashtable<String, String> params)
{
super(params);
}
// added constructor
public MySubClass(final Hashtable<String, String> params,
final FooBar fooBar)
{
super(params, fooBar);
}
}
// unchanged
class GlobalClass
{
public static Car GLOBALVAR;
}
// added interface
interface FooBar
{
Foo getFoo();
Bar getBar();
}
class Car
// added implements
implements FooBar
{
private Foo foo = new Foo();
private Bar bar = new Bar();
public Object get(final String name)
{
if(name.equals("foo"))
{
return (foo);
}
if(name.equals("bar"))
{
return (bar);
}
throw new Error();
}
// added method
public Foo getFoo()
{
return ((Foo)get("foo"));
}
// added method
public Bar getBar()
{
return ((Bar)get("bar"));
}
}
// unchanged
class Foo
{
}
// unchanged
class Bar
{
}
I think you should introduce an interface to put a layer of abstraction between the global variable collection and its consumers.
interface GlobalVars {
String get(String key);
}
You should introduce a constructor with limited scope, probably package-private
MyClass(GlobalVars globals, Map<String, String> params) {
// create the object
}
And then provide public static factory methods to use this constructor.
public static MyClass newMyClass(Map<String, String> params) {
return new MyClass(GlobalClass.GLOBAL_VAR, params);
}
With this design you can pass in a mock implementation of GlobalVars in a unit test from within the same package by explicitly invoking the constructor.
Addendum: Since params seems to be a required field, I would definitely make it final and avoid the approach where you add mutators to overwrite them.
private final Map<String, String> params;
Also, make a defensive copy to prevent l33t h4x.
this.params = Collections.unmodifiableMap(params);
Your class should take all of its dependencies in the constructor. It's a good idea to make it impossible to create an invalid or uninitialized instance of classes. Make foo and bar private and final, and set them in the constructor.
A slight variation on your approach would be to have an object of type GLOBALVAR in the class and use that instead of the actual global (that refactoring should be a simple search/replace). You can default the new variable to the actual global variable and provide an override for testing.
This GlobalClass.GLOBALVAR should be chopped up up into logical units. That way it would be easier to make mock objects for the unit tests. For example in my CAD/CAM metal cutting application I have a MaterialList, a SheetSizeList, PartNestingParameters, etc.
I don't have a huge list of variables stuff into one giant AppParameter class. They all hang off a ShopStandards object. For Unit Test involving a specific PartNestingParmeters I will just go ShopStandards.PartNestingParmeters = new MockPartNestingParameterTest114(). The test will run not realizing that the Part Nesting Parameters are a mockup. Plus this save me from having to doing dozens of assignments just to get the ShopStandard setup correctly for the test.
We have even more automated where many of the Mock load from files saved during the test run during initial development.
Since you mention that you have the freedom to modify the class hierarchy.
Change the base MyClass ctor to take in 3 parameters params, foo and bar. Comment out the GlobalVar references and simply cache passed in values
Compile.. this should throw up a bunch of compile errors - no ctor which takes 1 parameter.
Fix each one to pass in GlobalVar.get("foo") and GlobalVar.get("bar"). Get it to build.
Refine: Now minimize hits to the DB by lazy load and caching the foo and bar values. Expose via some property on GlobalVar.