Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Revision as of 11:32, 22 July 2013 by hamishwillee (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

How to access a synchronized method with multithreading

From Wiki
Jump to: navigation, search

This article explains how to access a synchronized method with Java, from several objects or instances of the same object. This is particularly useful in a multithread environment, when the operations performed by the application, require access to the same method and the method's code needs to be executed by one thread at a time. By synchronizing the access to the method's code, we can ensure that all the threads, but the one executing the synchronized method, are suspended and check on regular intervals whether the lock to the synchronized method has been released.

Contents

The Multiple connections example

In this example, multiple HTTP connections are attempted, by three instances of the same connection class. Each instance tries to load the content of a different web page and display its title. The fetch method provides the code that performs the retrieval of the page's content. Each instance needs to access the fetch method, while the latter should be only accessed by one instance at the time. Please note that, by synchronizing the fetch method, we can not ensure the order with which the instances will access the method, but only that the method will be accessed by a single instance and its thread. When the thread completes its tasks, it releases the lock so that one of sleeping threads gets the lock and repeats the cycle. The suspended threads are set to sleep for 2 seconds, then get active, check if it is their turn, and either execute the synchronized method or get suspended again.

Performance considerations

When performing operations that could take long time to complete, it makes sense to suspend any waiting threads for a period of time relative to the operation at hand. In this example 2 seconds was chosen, given that this is regarded as enough for the active thread to perform the connect operation. It is also possible to remove entirely the call to the sleep method, but this would deteriorate performance, specially on Series 40 devices due to the continuous execution of the while loop.


Implementing the MultipleConnections MIDlet

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
 
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
 
public class MultipleConnections extends MIDlet implements CommandListener{
 
Form mainform;
Command infoCommand=new Command("Info",Command.OK,1);
Command exitCommand=new Command("Exit",Command.EXIT,0);
connection con1;
connection con2;
connection con3;
boolean istaken;
 
protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException {}
 
protected void pauseApp() { }
 
protected void startApp() throws MIDletStateChangeException {
istaken=false;
mainform=new Form("Multi Connections");
mainform.addCommand(infoCommand);
mainform.addCommand(exitCommand);
con1=new connection(this,"http://www.w3schools.com/html/default.asp");
con2=new connection(this,"http://www.w3schools.com/html/html_fonts.asp");
con3=new connection(this,"http://www.w3schools.com/html/html_xhtml.asp");
mainform.setCommandListener(this);
Display.getDisplay(this).setCurrent(mainform);
}
public boolean isTaken()
{
return istaken;
}
public Form getForm()
{
return mainform;
}
public void commandAction(Command arg0, Displayable arg1) {
if(arg0==exitCommand)
{
notifyDestroyed();
}
if(arg0==infoCommand)
{
mainform.append("\nMIDlet is responsive\n");
}
}
public synchronized void fetch(String targetUrl)
{
istaken=true;
mainform.append("\nRetrieving page...\n");
String response="";
String substr="";
HttpConnection connection = null;
InputStream inputstream = null;
try
{
connection = (HttpConnection) Connector.open(targetUrl);
//HTTP Request
connection.setRequestMethod(HttpConnection.GET);
// HTTP Response
if (connection.getResponseCode() == HttpConnection.HTTP_OK)
{
inputstream = connection.openInputStream();
int length = (int) connection.getLength();
if (length != -1)
{
byte incomingData[] = new byte[length];
inputstream.read(incomingData);
response = new String(incomingData);
}
else
{
ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
int ch;
while ((ch = inputstream.read()) != -1)
{
bytestream.write(ch);
}
response = new String(bytestream.toByteArray());
bytestream.close();
}
}
}
catch(IOException error)
{
System.out.println("Caught IOException: " + error.toString());
}
finally
{
if (inputstream!= null)
{
try
{
inputstream.close();
}
catch( Exception error)
{
/*log error*/
}
}
if (connection != null)
{
try
{
connection.close();
}
catch( Exception error)
{
/*log error*/
}
}
}
if(response.indexOf("<title>")>=1 && response.indexOf("</title>")>=1)
{
int start=response.indexOf("<title>");
int end=response.indexOf("</title>");
substr=response.substring(start+7,end);
mainform.append("The title of the page is: "+substr);
}
else
{
mainform.append("The title of the page could not be retrieved");
}
mainform.append("\nDone!\n\n");
istaken=false;
}
}


Implementing the connection Class

public class connection implements Runnable{
static boolean istaken=false;
Thread t;
MultipleConnections midlet;
String targetUrl;
 
connection(MultipleConnections mid,String url)
{
midlet=mid;
targetUrl=url;
t=new Thread(this);
t.start();
}
 
public void run() {
while(midlet.isTaken())
{
try
{
Thread.sleep(2000);
}
catch(Exception e){}
}
midlet.fetch(targetUrl);
}
 
 
}

Source and Binary Files

The code above can be downloaded from File:MultipleConnectionsSource.zip

The installation .jar and .jad files can be downloaded from File:MultipleConnectionsBinaries.zip

See also

Thread Class - CLDC 1.1


Article Metadata
Code ExampleTested with
Devices(s): C3-00
CompatibilityArticle
Created: skalogir (24 Nov 2011)
Reviewed: skalogir (24 Nov 2011)
Last edited: hamishwillee (22 Jul 2013)
This page was last modified on 22 July 2013, at 11:32.
50 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×