I am working on two apps, in one of my app "A" i applied retrofit 2.
This was the method i used to retrieve data.
But here in on Response the data retrieved in response body can be set to activity variables and can be used outside this method without getting null values.
public void fetch_information() {
ApiInterface = ApiClient.getApiClient().create(Api.class);
Call<List<City>> call = ApiInterface.GetCities();
call.enqueue(new Callback<List<City>>() {
#Override
public void onResponse(Call<List<City>> call, Response<List<City>> response) {
citylist = new ArrayList<City>();
citylist = response.body();
cities = new String[citylist.size()];
citiesid = new String[citylist.size()];
for (int i = 0; i < citylist.size(); i++) {
cities[i] = citylist.get(i).getCityName();
citiesid[i] = citylist.get(i).getCityId();
}
city_adapter = new ArrayAdapter<String>(Pay_Payment_X.this, android.R.layout.simple_list_item_1, cities);
city_adapter.setDropDownViewResource(R.layout.spinner_dropdown_layout);
City_Spinner.setAdapter(city_adapter);
}
#Override
public void onFailure(Call<List<City>> call, Throwable t) {
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
after applying this method and on debugging this method i will retain values of varaibles "cities" and "citiesid"out side onResponse.
But applying retrofit 2 similarly on another app "B", i did the same thing for retrieving data on different URL.
ApiUtil.getServiceClass().getAllPost().enqueue(new Callback<List<ApiObject>>() {
#Override
public void onResponse(Call<List<ApiObject>> call, Response<List<ApiObject>> response) {
if (response.isSuccessful()) {
List<ApiObject> postList = response.body();
try {
for (int i = 0; i < postList.size(); i++) {
String Name = postList.get(i).getGamesName();
mGamesName.add(Name);
}
} catch (Exception e) {
}
Log.d(TAG, "Returned count " + postList.size());
NewAdapter adapter = new NewAdapter(getApplicationContext(), postList);
recyclerView.setAdapter(adapter);
}
}
#Override
public void onFailure(Call<List<ApiObject>> call, Throwable t) {
//showErrorMessage();
Log.d(TAG, "error loading from API");
}
});
the data is retrievable inside onResponse but outside it shows null.
So here variables are not retaining values.
Why is this happening?
the only thing came to mind is retrieving data can take time while your code lines are being read and finding null values as data has not been received yet.
Also to mention in app "A" the data retrieved is huge but in app "B" only 3 objects with string values.But still in app"A" data is retrievable.
In app 2 did this for resolving my issue.
public void doRequest( final ApiCallback callback){
ApiUtil.getServiceClass().getAllPost().enqueue(new Callback<List<ApiObject>>() {
#Override
public void onResponse(Call<List<ApiObject>> call, Response<List<ApiObject>> response) {
if (response.isSuccessful()) {
List<ApiObject> postList = response.body();
callback.onSuccess(postList);
// apobject =response.body();
if(response.isSuccessful()) {
try {
for (int i = 0; i < postList.size(); i++) {
String Name = postList.get(i).getGamesName().toString();
mGamesName.add(Name);
}
} catch (Exception e) {
}
}
Log.d(TAG, "Returned count " + postList.size());
NewAdapter adapter = new NewAdapter(getApplicationContext(), postList);
recyclerView.setAdapter(adapter);
}
}
#Override
public void onFailure(Call<List<ApiObject>> call, Throwable t) {
//showErrorMessage();
Log.d(TAG, "error loading from API");
}
});
}
pass an interface
public interface ApiCallback{
void onSuccess(List<ApiObject> result);
}
and in on Create view of activity i called this
doRequest(new ApiCallback(){
#Override
public void onSuccess(List<ApiObject> result){
//here i can set variable values
}
});
the only thing came to mind is retrieving data can take time while your code lines are being read and finding null values as data has not been received yet.
That's entirely correct. Your call is finishing after you check the values. I'm going to go on a limb here and say that it's just a coincidence that it works on one app and not in the other (if they are actually doing it the same way)
When you call callback.onSuccess(postList); doesn't seem to be right either, because you haven't checked yet for success. This means that response.body() might be null and response.errorBody() will contain the body of the error.
If you'd move callback.onSuccess inside the if this would be fixed:
if(response.isSuccessful()) {
callback.onSuccess(response.body());
try {
for (int i = 0; i < postList.size(); i++) {
String Name = postList.get(i).getGamesName().toString();
mGamesName.add(Name);
}
} catch (Exception e) {
}
Last but not least, inside the onSuccess method is when you can use your global variables. Maybe it's better to stop using global variables and just use the callback parameters.
I have been through many posts and questions but none of them had a absolute Java program to implement this.
Requirement : For some reasons my application loads the Common-codec 1.3.jar,
and later on ,within same jvm the process needs to use Common-code 1.10.jar which is of different version.
But since the previous classes are loaded and they have same package name ,reloading them with a Java program is not replacing the existing classes.
Here is the code (sample) i used to reload(replace) the existing keys,but found no luck as expected. Please let me know hoe this could be done by a Java example.
String pathToJar=/root/Desktop/commons-codec-1.10.jar";
JarFile jarFile = null;
try {
jarFile = new JarFile(pathToJar);
} catch (IOException e) {
e.printStackTrace();
}
Enumeration<JarEntry> e = jarFile.entries();
URL[] urls = new URL[0];
try {
urls = new URL[]{ new URL("jar:file:" + pathToJar+"!/") };
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
URLClassLoader cl = URLClassLoader.newInstance(urls);
while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
if(je.isDirectory() || !je.getName().endsWith(".class")){
continue;
}
// -6 because of .class
String className = je.getName().substring(0,je.getName().length()-6);
className = className.replace(File.separatorChar, '.');
String check="org.apache.commons.codec.binary.Base32";
try {
Class c = cl.loadClass(className); // Excepting it to replace old files,but thats not happening
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
I was advised to write Custom class loader and unloading is possible via it.
Could some show some relevant code or process of doing it.
Class "unloading" may only occur when both the Class and the ClassLoader that defined it are eligible for garbage collection. Furthermore, any given loader can only define a class of a specific name once. Therefore (save for exotic workarounds such as instrumentation or JDK implementation internals), there is no such thing as a "reloading-capable class loader" -- at least not in the true sense of the term; in order to obtain n distinct "versions" of a class, C, defineClass(C) must be invoked on n distinct ClassLoader objects.
Let's examine the following trivial use case: We have an app.jar, (unsurprisingly) containing a class declaring a main method; and two copies of a lib.jar, each having a single class, LibApiImpl, encapsulating a single method that just prints a version-dependent string to stdout. Our goal is to merely reference two copies of the "library" class from our main and see two different strings being output. The remainder of this post demonstrates just two of all the possible approaches to satisfy this requirement.
Approach #1 - Manually instantiating ClassLoaders
The straightforward solution is to simply create a new URLClassLoader every time a different LibApiImpl needs to be loaded. No custom class loader implementation is required, and the default parent-first delegation model serves both the application and the library well. A couple of things to note:
The library JARs must not sit on the classpath, in order to not be discoverable by the default application class loader. Otherwise the application class loader will "favor" one over the other, and, due to the default delegation model, standard URLClassLoader children of the application loader will not be able to override their parent's opinion on the matter.
To access the library class, the 3-argument Class::forName must be employed, specifying the manually-instantiated class loader. The single-arg version will delegate to the application class loader, which (as per the former point) is of course unaware of the existence of the corresponding .class file.
If the reflectively-obtained class is to be cast to an interface, as will be the case herein, the interface must, as opposed to the implementation, reside on the classpath.
Demo code
package com.example.app;
import java.net.URL;
import java.net.URLClassLoader;
import com.example.lib.api.LibApi;
public class App {
public static void main(String... args) throws Exception {
try (URLClassLoader loader = new URLClassLoader(new URL[] { new URL("file:/path/to/lib1.jar") })) {
((LibApi) Class.forName("com.example.lib.impl.LibApiImpl", true, loader).newInstance()).printVersionInfo();
}
try (URLClassLoader loader = new URLClassLoader(new URL[] { new URL("file:/path/to/lib2.jar") })) {
((LibApi) Class.forName("com.example.lib.impl.LibApiImpl", true, loader).newInstance()).printVersionInfo();
}
}
}
package com.example.lib.api;
public interface LibApi {
void printVersionInfo();
}
package com.example.lib.impl;
import com.example.lib.api.LibApi;
public class LibApiImpl implements LibApi {
#Override
public void printVersionInfo() {
System.out.println("\n** lib " + getClass() + " / loaded by " + getClass().getClassLoader() + " **\n");
}
}
Packaging
Correct the paths in com.example.app.App; then produce the following 4 JARs:
An app.jar containing the com.example.app package.
A lib-api.jar containing the com.example.lib.api package.
Two "versions" (just export twice), lib1.jar and lib2.jar, each containing the com.example.lib.impl package.
Testing
Run as follows:
java -cp '/path/to/app.jar:/path/to/lib-api.jar' com.example.app.App
Sample output:
** lib class com.example.lib.impl.LibApiImpl / loaded by java.net.URLClassLoader#55f96302 **
** lib class com.example.lib.impl.LibApiImpl / loaded by java.net.URLClassLoader#135fbaa4 **
Approach #2 - Creating a "Master-Slave" loader
Sometimes the "parent-first" model is insufficient. As a contrived example, suppose that we wanted to obtain the "copy" of LibApiImpl that was last loaded by some child of the application class loader, without having to care about which child it actually was that defined the copy. In other words, we want the call Class.forName("com.example.lib.impl.LibApiImpl") to return the "most fresh" LibApiImpl version. But, unless we override the application class loader, or, more generally, the class loader of the App class, with a custom implementation, that call will always fail, because, under the default delegation model, delegation flows unidirectionally from lower-level loaders to their ancestors and not vice versa.
The application class loader implementation, given below, behaves as follows (refer to the Javadoc overview of the Loaders class for a concrete explanation): There is a "master" loader, serving as the application class loader, that may have a child, referred to as its "slave". The master is responsible for loading non-reloadable application classes from the classpath (app.jar and lib-api.jar, in this case), while the slave gets to load reloadable, non-classpath-residing ones (lib1.jar and lib2.jar). The communication between the two is bidirectional, and the loader that will ultimately define any given class, "fixed" or "reloadable", is always respectively the master and the slave, regardless the "initiating" loader, i.e., the loader on which the application called loadClass, or passed to Class::forName. Of course this is nothing but a toy implementation meant to (hopefully) illustrate how a different delegation scheme might look like, and is probably flawed in ways I have not even begun to imagine. A real-world implementation would, e.g., have to provide proper concurrency; provide compliant implementations of getResource et al.; address concerns of code accessibility, verification, and possibly code base privilege assignment; and allow extensibility by, and configuration of, multiple slaves, or even attachment of other children, potentially of arbitrary implementation, to the master, while preserving well-defined delegation semantics. The point of course being that it is generally too much effort to write a proper implementation, when there is OSGi and the like doing just that (among many others).
Demo code
package com.example.app;
import java.net.URL;
import com.example.app.Loaders.MasterLoader;
import com.example.lib.api.LibApi;
public class App2 {
public static void main(String... args) throws Exception {
MasterLoader loader = (MasterLoader) ClassLoader.getSystemClassLoader();
loader.setDebug(true);
loader.refresh(new URL[] { new URL("file:/path/to/lib1.jar") });
newLibApi().printVersionInfo();
loader.refresh(new URL[] { new URL("file:/path/to/lib2.jar") });
newLibApi().printVersionInfo();
}
static LibApi newLibApi() throws Exception {
return (LibApi) Class.forName("com.example.lib.impl.LibApiImpl").newInstance();
}
}
package com.example.app;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
/**
* Contains a "Master (parent)/Slave (child)" <code>ClassLoader</code> "duo".<br/>
* <br/>
* The class loading "protocol" adhered by the respective {#code loadClass(String, boolean)}
* implementations of the two is as follows:
* <ol>
* <li>If the name argument matches the name of the loader's class itself, return that class.
* Otherwise proceed.</li>
* <li>If a call to {#code findLoadedClass(name)} yields a non-null class, return that class.
* Otherwise proceed.</li>
* <li>Let <em>C</em> be either this loader's parent, if this is a "slave", or its child, if this is
* a "master". If <em>C</em> is non-null, have it execute steps (1), (2) itself. If a class gets
* produced, return that class. Otherwise (i.e., if there either is no result, or <em>C</em> is
* null) proceed.</li>
* <li>If the name argument refers to a potential bootstrap classpath class name, call
* {#code loadClass(name)} on the default system classloader (the "master's" parent). If the call
* succeeds, return that class. Otherwise proceed.</li>
* <li>If the name argument refers to a .class file under this loader's search path, read it, define
* and link a new class off of its contents, and return that "freshly-fefined" class. Otherwise
* proceed.</li>
* <li>Once again, let <em>C</em> be the loader specified in step (3). If non-null, have it execute
* step (5) on itself. If a class gets produced, return that class. Otherwise fail.</li>
* </ol>
*/
public class Loaders {
private static class SlaveLoader extends URLClassLoader {
static final Pattern BOOT_CLASS_PATH_RES_NAMES = Pattern.compile("((com\\.)?sun|java(x)?)\\..*");
static final URL[] EMPTY_SEARCH_PATH = new URL[0];
static final URL[] createSearchPath(String pathNames) {
if (pathNames != null) {
List<URL> searchPath = new ArrayList<>();
for (String pathName : pathNames.split(File.pathSeparator)) {
try {
searchPath.add(Paths.get(pathName).toUri().toURL());
}
catch (MalformedURLException e) {
e.printStackTrace();
}
}
return searchPath.toArray(new URL[0]);
}
return EMPTY_SEARCH_PATH;
}
static final byte[] readClassData(URL classResource) throws IOException {
try (InputStream in = classResource.openStream(); ByteArrayOutputStream out = new ByteArrayOutputStream()) {
while (in.available() > 0) {
out.write(in.read());
}
return out.toByteArray();
}
}
final String loadClassOutcomeMsgFmt = "loadClass return '{'\n\tloader = {0}\n\ttarget = {1}\n\tresult : {2}\n'}'";
volatile boolean debug;
SlaveLoader(URL[] searchPath, ClassLoader parent) {
super(searchPath, parent);
}
#Override
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
validateName(name);
Class<?> ret = loadFromCache(name);
if (ret != null) {
return ret;
}
MasterLoader parent = (MasterLoader) getParent();
if ((ret = parent.loadFromCache(name)) != null) {
log(loadClassOutcomeMsgFmt, this, name, "3 - early return - pre-loaded/cached - via " + parent);
return ret;
}
if ((ret = loadFromBootClasspath(name)) != null) {
return ret;
}
if ((ret = loadFromSearchPath(name, resolve)) != null) {
return ret;
}
if ((ret = parent.loadFromSearchPath(name, resolve)) != null) {
log(loadClassOutcomeMsgFmt, this, name,
"6 - common/non-reloadable classpath delegation - via " + parent);
return ret;
}
if ((ret = parent.loadFromSearchPath(name, resolve)) != null) {
return ret;
}
throw createCnfe(name, null);
}
void validateName(String name) throws ClassNotFoundException {
log("loadClass entry '{'\n\tloader = {0}\n\ttarget = {1}\n'}'", this, name);
if ((name == null) || name.trim().isEmpty()) {
throw createCnfe(name, null);
}
}
Class<?> loadFromCache(String name) {
Class<?> ret = getClass();
if (ret.getName().equals(name)) {
log(loadClassOutcomeMsgFmt, this, name, "1 - early return - own class");
return ret;
}
if ((ret = findLoadedClass(name)) != null) {
log(loadClassOutcomeMsgFmt, this, name, "2 - early return - pre-loaded/cached");
return ret;
}
return null;
}
Class<?> loadFromBootClasspath(String name) {
if (BOOT_CLASS_PATH_RES_NAMES.matcher(name).matches()) {
ClassLoader defSysCl = ClassLoader.getSystemClassLoader().getParent();
try {
Class<?> ret = ClassLoader.getSystemClassLoader().getParent().loadClass(name);
log(loadClassOutcomeMsgFmt, this, name, "4 - bootstrap classpath delegation - via " + defSysCl);
return ret;
}
catch (ClassNotFoundException cnfe) {
}
}
return null;
}
Class<?> loadFromSearchPath(String name, boolean resolve) throws ClassNotFoundException {
Class<?> ret = null;
URL res = findResource(name.replace(".", "/") + ".class");
if (res != null) {
byte[] b;
try {
b = readClassData(res);
}
catch (IOException ioe) {
throw createCnfe(name, ioe);
}
ret = defineClass(name, b, 0, b.length);
if (resolve) {
resolveClass(ret);
}
log(loadClassOutcomeMsgFmt, this, name, "5 - freshly-defined from local search path");
return ret;
}
return null;
}
ClassNotFoundException createCnfe(String name, Throwable cause) throws ClassNotFoundException {
return new ClassNotFoundException(MessageFormat.format("Class loading : {0} : {1} : FAILED", this,
(name == null) ? "null" : name, cause));
}
void log(String msg, Object... args) {
if (debug) {
System.out.println(MessageFormat.format("\n" + msg + "\n", args));
}
}
public void setDebug(boolean debug) {
this.debug = debug;
}
#Override
protected void finalize() throws Throwable {
try {
close();
}
finally {
super.finalize();
}
log("ClassLoader finalization : {0}", this);
}
}
public static class MasterLoader extends SlaveLoader {
static final URL[] DEFAULT_CLASS_PATH = createSearchPath(System.getProperty("java.class.path"));
private URL[] reloadableSearchPath = EMPTY_SEARCH_PATH;
private volatile SlaveLoader slave;
public MasterLoader(ClassLoader parent) {
super(DEFAULT_CLASS_PATH, parent);
}
public synchronized void refresh(URL[] reloadableSearchPath) {
int len;
if ((reloadableSearchPath != null) && ((len = reloadableSearchPath.length) > 0)) {
List<URL> path = new ArrayList<>(len + 1);
for (int i = 0; i < len; i++) {
URL entry = reloadableSearchPath[i];
if (entry != null) {
path.add(entry);
}
}
this.reloadableSearchPath = (!path.isEmpty()) ? path.toArray(EMPTY_SEARCH_PATH) : EMPTY_SEARCH_PATH;
}
else {
this.reloadableSearchPath = EMPTY_SEARCH_PATH;
}
if (slave != null) {
try {
slave.close();
}
catch (IOException ioe) {
}
slave = null;
/*
* At least two calls to System::gc appear to be required in order for Class::forName to cease
* returning cached classes previously defined by slave and for which the master served as an
* intermediary, i.e., an "initiating loader".
*
* See also http://blog.hargrave.io/2007/09/classforname-caches-defined-class-in.html
*/
for (int i = 0; i < 2; i++) {
System.gc();
try {
Thread.sleep(100);
}
catch (InterruptedException ie) {
}
}
}
if (this.reloadableSearchPath != EMPTY_SEARCH_PATH) {
log("Class loader search path refresh : {0}\n\tSearch path = {1}", this,
Arrays.toString(this.reloadableSearchPath));
slave = new SlaveLoader(this.reloadableSearchPath, this);
slave.setDebug(debug);
}
}
#Override
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
validateName(name);
Class<?> ret = loadFromCache(name);
if (ret != null) {
return ret;
}
if ((slave != null) && ((ret = slave.loadFromCache(name)) != null)) {
log(loadClassOutcomeMsgFmt, this, name, "3 - early return - pre-loaded/cached - via " + slave);
return ret;
}
if ((ret = loadFromBootClasspath(name)) != null) {
return ret;
}
if ((ret = loadFromSearchPath(name, resolve)) != null) {
return ret;
}
if ((slave != null) && ((ret = slave.loadFromSearchPath(name, resolve)) != null)) {
log(loadClassOutcomeMsgFmt, this, name,
"6 - reloadable classpath delegation - via " + ret.getClassLoader());
return ret;
}
throw createCnfe(name, null);
}
}
}
Packaging
Once again correct the paths in com.example.app.App2; add App2 and com.example.app.Loaders to app.jar; and re-export. The other JARs should remain as in the former example.
Testing
Run as follows:
java -cp '/path/to/app.jar:/path/to/lib-api.jar' \
'-Djava.system.class.loader=com.example.app.Loaders$MasterLoader' \
com.example.app.App2
Sample output (loadClass debug omitted):
** lib class com.example.lib.impl.LibApiImpl / loaded by com.example.app.Loaders$SlaveLoader#7f31245a **
...
ClassLoader finalization : com.example.app.Loaders$SlaveLoader#7f31245a
...
** lib class com.example.lib.impl.LibApiImpl / loaded by com.example.app.Loaders$SlaveLoader#12a3a380 **
I understand what livelock is, but I was wondering if anyone had a good code-based example of it? And by code-based, I do not mean "two people trying to get past each other in a corridor". If I read that again, I'll lose my lunch.
Here's a very simple Java example of livelock where a husband and wife are trying to eat soup, but only have one spoon between them. Each spouse is too polite, and will pass the spoon if the other has not yet eaten.
public class Livelock {
static class Spoon {
private Diner owner;
public Spoon(Diner d) { owner = d; }
public Diner getOwner() { return owner; }
public synchronized void setOwner(Diner d) { owner = d; }
public synchronized void use() {
System.out.printf("%s has eaten!", owner.name);
}
}
static class Diner {
private String name;
private boolean isHungry;
public Diner(String n) { name = n; isHungry = true; }
public String getName() { return name; }
public boolean isHungry() { return isHungry; }
public void eatWith(Spoon spoon, Diner spouse) {
while (isHungry) {
// Don't have the spoon, so wait patiently for spouse.
if (spoon.owner != this) {
try { Thread.sleep(1); }
catch(InterruptedException e) { continue; }
continue;
}
// If spouse is hungry, insist upon passing the spoon.
if (spouse.isHungry()) {
System.out.printf(
"%s: You eat first my darling %s!%n",
name, spouse.getName());
spoon.setOwner(spouse);
continue;
}
// Spouse wasn't hungry, so finally eat
spoon.use();
isHungry = false;
System.out.printf(
"%s: I am stuffed, my darling %s!%n",
name, spouse.getName());
spoon.setOwner(spouse);
}
}
}
public static void main(String[] args) {
final Diner husband = new Diner("Bob");
final Diner wife = new Diner("Alice");
final Spoon s = new Spoon(husband);
new Thread(new Runnable() {
public void run() { husband.eatWith(s, wife); }
}).start();
new Thread(new Runnable() {
public void run() { wife.eatWith(s, husband); }
}).start();
}
}
Run the program and you'll get:
Bob: You eat first my darling Alice!
Alice: You eat first my darling Bob!
Bob: You eat first my darling Alice!
Alice: You eat first my darling Bob!
Bob: You eat first my darling Alice!
Alice: You eat first my darling Bob!
...
This will go on forever if uninterrupted. This is a livelock because both Alice and Bob are repeatedly asking each other to go first in an infinite loop (hence live). In a deadlock situation, both Alice and Bob would simply be frozen waiting on each other to go first — they won't be doing anything except wait (hence dead).
Flippant comments aside, one example which is known to come up is in code which tries to detect and handle deadlock situations. If two threads detect a deadlock, and try to "step aside" for each other, without care they will end up being stuck in a loop always "stepping aside" and never managing to move forwards.
By "step aside" I mean that they would release the lock and attempt to let the other one acquire it. We might imagine the situation with two threads doing this (pseudocode):
// thread 1
getLocks12(lock1, lock2)
{
lock1.lock();
while (lock2.locked())
{
// attempt to step aside for the other thread
lock1.unlock();
wait();
lock1.lock();
}
lock2.lock();
}
// thread 2
getLocks21(lock1, lock2)
{
lock2.lock();
while (lock1.locked())
{
// attempt to step aside for the other thread
lock2.unlock();
wait();
lock2.lock();
}
lock1.lock();
}
Race conditions aside, what we have here is a situation where both threads, if they enter at the same time will end up running in the inner loop without proceeding. Obviously this is a simplified example. A naiive fix would be to put some kind of randomness in the amount of time the threads would wait.
The proper fix is to always respect the lock heirarchy. Pick an order in which you acquire the locks and stick to that. For example if both threads always acquire lock1 before lock2, then there is no possibility of deadlock.
As there is no answer marked as accepted answer, I have attempted to create live lock example;
Original program was written by me in Apr 2012 to learn various concept of multithreading. This time I have modified it to create deadlock, race condition, livelock etc.
So let's understand the problem statement first;
Cookie Maker Problem
There are some ingredient containers: ChocoPowederContainer, WheatPowderContainer. CookieMaker takes some amount of powder from ingredient containers to bake a Cookie. If a cookie maker finds a container empty it checks for another container to save time. And waits until Filler fills the required container. There is a Filler who checks container on regular interval and fills some quantity if a container needs it.
Please check the complete code on github;
Let me explain you implementation in brief.
I start Filler as daemon thread. So it'll keep filling containers on regular interval. To fill a container first it locks the container -> check if it needs some powder -> fills it -> signal all makers who are waiting for it -> unlock container.
I create CookieMaker and set that it can bake up to 8 cookies in parallel. And I start 8 threads to bake cookies.
Each maker thread creates 2 callable sub-thread to take powder from containers.
sub-thread takes a lock on a container and check if it has enough powder. If not, wait for some time. Once Filler fills the container, it takes the powder, and unlock the container.
Now it completes other activities like: making mixture and baking etc.
Let's have a look in the code:
CookieMaker.java
private Integer getMaterial(final Ingredient ingredient) throws Exception{
:
container.lock();
while (!container.getIngredient(quantity)) {
container.empty.await(1000, TimeUnit.MILLISECONDS);
//Thread.sleep(500); //For deadlock
}
container.unlock();
:
}
IngredientContainer.java
public boolean getIngredient(int n) throws Exception {
:
lock();
if (quantityHeld >= n) {
TimeUnit.SECONDS.sleep(2);
quantityHeld -= n;
unlock();
return true;
}
unlock();
return false;
}
Everything runs fine until Filler is filling the containers. But if I forget to start the filler, or filler goes on unexpected leave, sub-threads keep changing their states to allow other maker to go and check the container.
I have also create a daemon ThreadTracer which keeps watch on thread states and deadlocks. This the output from console;
2016-09-12 21:31:45.065 :: [Maker_0:WAITING, Maker_1:WAITING, Maker_2:WAITING, Maker_3:WAITING, Maker_4:WAITING, Maker_5:WAITING, Maker_6:WAITING, Maker_7:WAITING, pool-7-thread-1:TIMED_WAITING, pool-7-thread-2:TIMED_WAITING, pool-8-thread-1:TIMED_WAITING, pool-8-thread-2:TIMED_WAITING, pool-6-thread-1:TIMED_WAITING, pool-6-thread-2:TIMED_WAITING, pool-5-thread-1:TIMED_WAITING, pool-5-thread-2:TIMED_WAITING, pool-1-thread-1:TIMED_WAITING, pool-3-thread-1:TIMED_WAITING, pool-2-thread-1:TIMED_WAITING, pool-1-thread-2:TIMED_WAITING, pool-4-thread-1:TIMED_WAITING, pool-4-thread-2:RUNNABLE, pool-3-thread-2:TIMED_WAITING, pool-2-thread-2:TIMED_WAITING]
2016-09-12 21:31:45.065 :: [Maker_0:WAITING, Maker_1:WAITING, Maker_2:WAITING, Maker_3:WAITING, Maker_4:WAITING, Maker_5:WAITING, Maker_6:WAITING, Maker_7:WAITING, pool-7-thread-1:TIMED_WAITING, pool-7-thread-2:TIMED_WAITING, pool-8-thread-1:TIMED_WAITING, pool-8-thread-2:TIMED_WAITING, pool-6-thread-1:TIMED_WAITING, pool-6-thread-2:TIMED_WAITING, pool-5-thread-1:TIMED_WAITING, pool-5-thread-2:TIMED_WAITING, pool-1-thread-1:TIMED_WAITING, pool-3-thread-1:TIMED_WAITING, pool-2-thread-1:TIMED_WAITING, pool-1-thread-2:TIMED_WAITING, pool-4-thread-1:TIMED_WAITING, pool-4-thread-2:TIMED_WAITING, pool-3-thread-2:TIMED_WAITING, pool-2-thread-2:TIMED_WAITING]
WheatPowder Container has 0 only.
2016-09-12 21:31:45.082 :: [Maker_0:WAITING, Maker_1:WAITING, Maker_2:WAITING, Maker_3:WAITING, Maker_4:WAITING, Maker_5:WAITING, Maker_6:WAITING, Maker_7:WAITING, pool-7-thread-1:TIMED_WAITING, pool-7-thread-2:TIMED_WAITING, pool-8-thread-1:TIMED_WAITING, pool-8-thread-2:TIMED_WAITING, pool-6-thread-1:TIMED_WAITING, pool-6-thread-2:TIMED_WAITING, pool-5-thread-1:TIMED_WAITING, pool-5-thread-2:TIMED_WAITING, pool-1-thread-1:TIMED_WAITING, pool-3-thread-1:TIMED_WAITING, pool-2-thread-1:TIMED_WAITING, pool-1-thread-2:TIMED_WAITING, pool-4-thread-1:TIMED_WAITING, pool-4-thread-2:TIMED_WAITING, pool-3-thread-2:TIMED_WAITING, pool-2-thread-2:RUNNABLE]
2016-09-12 21:31:45.082 :: [Maker_0:WAITING, Maker_1:WAITING, Maker_2:WAITING, Maker_3:WAITING, Maker_4:WAITING, Maker_5:WAITING, Maker_6:WAITING, Maker_7:WAITING, pool-7-thread-1:TIMED_WAITING, pool-7-thread-2:TIMED_WAITING, pool-8-thread-1:TIMED_WAITING, pool-8-thread-2:TIMED_WAITING, pool-6-thread-1:TIMED_WAITING, pool-6-thread-2:TIMED_WAITING, pool-5-thread-1:TIMED_WAITING, pool-5-thread-2:TIMED_WAITING, pool-1-thread-1:TIMED_WAITING, pool-3-thread-1:TIMED_WAITING, pool-2-thread-1:TIMED_WAITING, pool-1-thread-2:TIMED_WAITING, pool-4-thread-1:TIMED_WAITING, pool-4-thread-2:TIMED_WAITING, pool-3-thread-2:TIMED_WAITING, pool-2-thread-2:TIMED_WAITING]
You'll notice that sub-threads and changing their states and waiting.
A real (albeit without exact code) example is two competing processes live locking in an attempt to correct for a SQL server deadlock, with each process using the same wait-retry algorithm for retrying. While it's the luck of timing, I have seen this happen on separate machines with similar performance characteristics in response to a message added to an EMS topic (e.g. saving an update of a single object graph more than once), and not being able to control the lock order.
A good solution in this case would be to have competing consumers (prevent duplicate processing as high up in the chain as possible by partitioning the work on unrelated objects).
A less desirable (ok, dirty-hack) solution is to break the timing bad luck (kind of force differences in processing) in advance or break it after deadlock by using different algorithms or some element of randomness. This could still have issues because its possible the lock taking order is "sticky" for each process, and this takes a certain minimum of time not accounted for in the wait-retry.
Yet another solution (at least for SQL Server) is to try a different isolation level (e.g. snapshot).
I coded up the example of 2 persons passing in a corridor. The two threads will avoid each other as soon as they realise their directions are the same.
public class LiveLock {
public static void main(String[] args) throws InterruptedException {
Object left = new Object();
Object right = new Object();
Pedestrian one = new Pedestrian(left, right, 0); //one's left is one's left
Pedestrian two = new Pedestrian(right, left, 1); //one's left is two's right, so have to swap order
one.setOther(two);
two.setOther(one);
one.start();
two.start();
}
}
class Pedestrian extends Thread {
private Object l;
private Object r;
private Pedestrian other;
private Object current;
Pedestrian (Object left, Object right, int firstDirection) {
l = left;
r = right;
if (firstDirection==0) {
current = l;
}
else {
current = r;
}
}
void setOther(Pedestrian otherP) {
other = otherP;
}
Object getDirection() {
return current;
}
Object getOppositeDirection() {
if (current.equals(l)) {
return r;
}
else {
return l;
}
}
void switchDirection() throws InterruptedException {
Thread.sleep(100);
current = getOppositeDirection();
System.out.println(Thread.currentThread().getName() + " is stepping aside.");
}
public void run() {
while (getDirection().equals(other.getDirection())) {
try {
switchDirection();
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}
}
C# version of jelbourn's code:
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace LiveLockExample
{
static class Program
{
public static void Main(string[] args)
{
var husband = new Diner("Bob");
var wife = new Diner("Alice");
var s = new Spoon(husband);
Task.WaitAll(
Task.Run(() => husband.EatWith(s, wife)),
Task.Run(() => wife.EatWith(s, husband))
);
}
public class Spoon
{
public Spoon(Diner diner)
{
Owner = diner;
}
public Diner Owner { get; private set; }
[MethodImpl(MethodImplOptions.Synchronized)]
public void SetOwner(Diner d) { Owner = d; }
[MethodImpl(MethodImplOptions.Synchronized)]
public void Use()
{
Console.WriteLine("{0} has eaten!", Owner.Name);
}
}
public class Diner
{
public Diner(string n)
{
Name = n;
IsHungry = true;
}
public string Name { get; private set; }
private bool IsHungry { get; set; }
public void EatWith(Spoon spoon, Diner spouse)
{
while (IsHungry)
{
// Don't have the spoon, so wait patiently for spouse.
if (spoon.Owner != this)
{
try
{
Thread.Sleep(1);
}
catch (ThreadInterruptedException e)
{
}
continue;
}
// If spouse is hungry, insist upon passing the spoon.
if (spouse.IsHungry)
{
Console.WriteLine("{0}: You eat first my darling {1}!", Name, spouse.Name);
spoon.SetOwner(spouse);
continue;
}
// Spouse wasn't hungry, so finally eat
spoon.Use();
IsHungry = false;
Console.WriteLine("{0}: I am stuffed, my darling {1}!", Name, spouse.Name);
spoon.SetOwner(spouse);
}
}
}
}
}
Consider a UNIX system having 50 process slots.
Ten programs are running, each of which having to create 6 (sub)processes.
After each process has created 4 processes, the 10 original processes and the 40 new processes have exhausted the table. Each of the 10 original processes now sits in an endless loop forking and failing – which is aptly the situation of a livelock. The probability of this happening is very little but it could happen.
One example here might be using a timed tryLock to obtain more than one lock and if you can't obtain them all, back off and try again.
boolean tryLockAll(Collection<Lock> locks) {
boolean grabbedAllLocks = false;
for(int i=0; i<locks.size(); i++) {
Lock lock = locks.get(i);
if(!lock.tryLock(5, TimeUnit.SECONDS)) {
grabbedAllLocks = false;
// undo the locks I already took in reverse order
for(int j=i-1; j >= 0; j--) {
lock.unlock();
}
}
}
}
I could imagine such code would be problematic as you have lots of threads colliding and waiting to obtain a set of locks. But I'm not sure this is very compelling to me as a simple example.
Python version of jelbourn's code:
import threading
import time
lock = threading.Lock()
class Spoon:
def __init__(self, diner):
self.owner = diner
def setOwner(self, diner):
with lock:
self.owner = diner
def use(self):
with lock:
"{0} has eaten".format(self.owner)
class Diner:
def __init__(self, name):
self.name = name
self.hungry = True
def eatsWith(self, spoon, spouse):
while(self.hungry):
if self != spoon.owner:
time.sleep(1) # blocks thread, not process
continue
if spouse.hungry:
print "{0}: you eat first, {1}".format(self.name, spouse.name)
spoon.setOwner(spouse)
continue
# Spouse was not hungry, eat
spoon.use()
print "{0}: I'm stuffed, {1}".format(self.name, spouse.name)
spoon.setOwner(spouse)
def main():
husband = Diner("Bob")
wife = Diner("Alice")
spoon = Spoon(husband)
t0 = threading.Thread(target=husband.eatsWith, args=(spoon, wife))
t1 = threading.Thread(target=wife.eatsWith, args=(spoon, husband))
t0.start()
t1.start()
t0.join()
t1.join()
if __name__ == "__main__":
main()
I modify the answer of #jelbourn.
When one of them notices that the other is hungry, he(her) should release the spoon and wait another notify, so a livelock happens.
public class LiveLock {
static class Spoon {
Diner owner;
public String getOwnerName() {
return owner.getName();
}
public void setOwner(Diner diner) {
this.owner = diner;
}
public Spoon(Diner diner) {
this.owner = diner;
}
public void use() {
System.out.println(owner.getName() + " use this spoon and finish eat.");
}
}
static class Diner {
public Diner(boolean isHungry, String name) {
this.isHungry = isHungry;
this.name = name;
}
private boolean isHungry;
private String name;
public String getName() {
return name;
}
public void eatWith(Diner spouse, Spoon sharedSpoon) {
try {
synchronized (sharedSpoon) {
while (isHungry) {
while (!sharedSpoon.getOwnerName().equals(name)) {
sharedSpoon.wait();
//System.out.println("sharedSpoon belongs to" + sharedSpoon.getOwnerName())
}
if (spouse.isHungry) {
System.out.println(spouse.getName() + "is hungry,I should give it to him(her).");
sharedSpoon.setOwner(spouse);
sharedSpoon.notifyAll();
} else {
sharedSpoon.use();
sharedSpoon.setOwner(spouse);
isHungry = false;
}
Thread.sleep(500);
}
}
} catch (InterruptedException e) {
System.out.println(name + " is interrupted.");
}
}
}
public static void main(String[] args) {
final Diner husband = new Diner(true, "husband");
final Diner wife = new Diner(true, "wife");
final Spoon sharedSpoon = new Spoon(wife);
Thread h = new Thread() {
#Override
public void run() {
husband.eatWith(wife, sharedSpoon);
}
};
h.start();
Thread w = new Thread() {
#Override
public void run() {
wife.eatWith(husband, sharedSpoon);
}
};
w.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
h.interrupt();
w.interrupt();
try {
h.join();
w.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package concurrently.deadlock;
import static java.lang.System.out;
/* This is an example of livelock */
public class Dinner {
public static void main(String[] args) {
Spoon spoon = new Spoon();
Dish dish = new Dish();
new Thread(new Husband(spoon, dish)).start();
new Thread(new Wife(spoon, dish)).start();
}
}
class Spoon {
boolean isLocked;
}
class Dish {
boolean isLocked;
}
class Husband implements Runnable {
Spoon spoon;
Dish dish;
Husband(Spoon spoon, Dish dish) {
this.spoon = spoon;
this.dish = dish;
}
#Override
public void run() {
while (true) {
synchronized (spoon) {
spoon.isLocked = true;
out.println("husband get spoon");
try { Thread.sleep(2000); } catch (InterruptedException e) {}
if (dish.isLocked == true) {
spoon.isLocked = false; // give away spoon
out.println("husband pass away spoon");
continue;
}
synchronized (dish) {
dish.isLocked = true;
out.println("Husband is eating!");
}
dish.isLocked = false;
}
spoon.isLocked = false;
}
}
}
class Wife implements Runnable {
Spoon spoon;
Dish dish;
Wife(Spoon spoon, Dish dish) {
this.spoon = spoon;
this.dish = dish;
}
#Override
public void run() {
while (true) {
synchronized (dish) {
dish.isLocked = true;
out.println("wife get dish");
try { Thread.sleep(2000); } catch (InterruptedException e) {}
if (spoon.isLocked == true) {
dish.isLocked = false; // give away dish
out.println("wife pass away dish");
continue;
}
synchronized (spoon) {
spoon.isLocked = true;
out.println("Wife is eating!");
}
spoon.isLocked = false;
}
dish.isLocked = false;
}
}
}
Example:
Thread 1
top:
lock(L1);
if (try_lock(L2) != 0) {
unlock(L1);
goto top;
Thread 2
top:
lock(L2);
if (try_lock(L1) != 0) {
unlock(L2);
goto top;
The only difference is Thread 1 and Thread 2 try to acquire the locks in a different order. Livelock could happen as follows:
Thread 1 runs acquires L1, then a context switch occurs. Thread 2 runs acquires L2, then another context switch occurs. Thread 1 runs and cannot acquire L2, but before releasing L1 a context switch occurs. Thread 2 runs and cannot acquire L1, releases L2, and a context switch occurs. Thread 1 releases L1, and now we are basically back to the starting state, and in theory these steps could keep repeating forever.