Unlike the doctor that works for your HMO, Doctor Java is
here to help you with all of your Java problems. The good Doc will
not require a copayment for each visit nor ask you to fill out long
arduous forms. The Doctor is here to help the readers of Java
Developer's Journal find a cure for their Java system ills.
How can I synchronize method access across two different classes?
The synchronized modifier is used to control access to
critical code in multithreaded programs. When a method is declared
synchronized, you're instructing the program to obtain a lock
(monitor) on the object that has the method. If you call another
synchronized method on the same object, you don't lose the lock and
other threads don't have access until the lock is freed.
This, however, does not work across objects. The best way to
solve this problem is not to declare your methods as synchronized but
to use a synchronized block. First, we'll look at typical code that
does not lock across methods:
public synchronized void
increasePaycheck(int empId, int percent) {
...
}
public synchronized void
givePromotion(int empId, String newTitle) {
...
}
Let's consider doing something like this:
public void increasePaycheck(int percent) {
synchronized(this);
...
}
This would be considered a noble effort but unfortunately it
does not do the trick. The main problem with this is that you are
still trying to acquire a lock on this. What we really need is an
alternative object to lock. Let's restructure our code and see how
this can be realized.
public HRObject {
private static Object lock = new Object();
public static void doIncreasePromotion
(int empID, int percent,
String newTitle) {
HRIncrease hr1 = new HRIncrease();
HRPromotion hr2 = new HRPromotion();
synchronized(lock) {
hr1.increasePaycheck(int empId, int percent);
hr2.givePromotion(int empId, String newTitle);
}
}
}
The preceding code example is the prescription for your
woes. We basically used an "impartial" object as the basis for
acquiring a lock. This approach requires that you always use the same
lock object and methods similar in their approach to synchronization.
We could have alternatively created a static method in a class that
is synchronized and have this method make all the other method calls
on your behalf.
I am building a JSP/JDBC site with an ISP that never allows a dsn
type connection. The database I want to use is access. How do I do a
dsn-less connection?
The doctor recommends seriously changing your diet and
eliminating Microsoft Access as a database for use with Java and
migrating to something that will scale a little better and is
supportable. With that being said, let's dive into the solution to
your problem. Let's say that you have an ODBC connection with the
following configuration:
[ODBC]
DRIVER=Microsoft Access Driver (*.mdb)
UID=admin
UserCommitSync=Yes
Threads=4
SafeTransactions=0
PageTimeout=5
MaxScanRows=8
MaxBufferSize=2048
FIL=MS Access
DriverId=25
DefaultDir=c:\
DBQ=c:\doctorjava.mdb
To talk to an ODBC data source you will need to utilize a
JDBC to ODBC bridge. Sun recommends using the bridge in situations
where no native JDBC driver exists. Merant is a company that provides
JDBC drivers that can connect to many disparate databases. To utilize
the bridge, your code would look similar to:
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn =
DriverManager.getConnection("jdbc:odbc:
DRIVER=Microsoft Access Driver
(*.mdb);" +
"DBQ=c:\\doctorjava.mdb");
...
}
The ODBC connection strings may vary in syntax depending upon
the actual database and language you are connecting to.
I would like to see all of the elements in the request header in my
JSP for debugging purposes. Could you point me in the right direction?
The doctor loves it when readers ask questions that can be
answered quickly. To solve your problem we can take advantage of the
java.util.Enumeration object. We can loop through the requests and
display them to the screen. Let's take a look at some sample code.
<html>
<head><title>Show Headers</title></head>
<body>
<%
java.util.Enumeration e=
request.getHeaderNames():
for (e; e.hasMoreElements();) {
String header=
(String)e.nextElement();
out.print(header + " = " +
request.getHeader(header) + "
");
}
%>
</body>
</html>
The doctor assumes the reason you have the need for such code
is because you are having a problem related to types not being set
properly on your Web server.
How do I delete a
cookie within a
JSP page?
Let's take a look at your code and see why it doesn't perform
as expected.
Cookie killCookie = new Cookie("uid", null);
killCookie.setMaxAge(0);
The code removes a cookie from the browser once the browser
is closed. This approach does not work in all instances. Many
browsers keep it in memory and will not actually destroy the cookie
until the browser instance is shut down. Let's take it one step
further. In some scenarios, it may be useful to have the cookie
destroyed without shutting down the browser. To realize this goal,
you need to change your code slightly as follows:
Cookie killCookie = new Cookie("uid", null);
killCookie.setMaxAge(0);
killCookie.setPath("/");
response.addCookie(killCookie);
This should do the trick nicely.
When should I use the singleton pattern in my java application?
The Singleton pattern reminds me of one of my girlfriends in high school. At first, I found
that she was the only thing I wanted but later she proved to be very
problematic. The Singleton pattern is useful in situations where you
only want to have a single instance of a particular object. The
second use for Singletons is to provide a global viewpoint of common
functionality. Typically, Singletons will be used for log managers,
reference services, and similar functionality.
Singletons can be problematic, like the girlfriend in high school
They're typically implemented with synchronized blocks. Many threads
will fight to obtain a lock on your Singleton causing a big
performance bottleneck. The Singleton pattern can be problematic in a
cluster as you will want more than one instance. The other problem
with this pattern is that you need to make sure that its access is
completely hidden from the outside world, or else it is essentially a
big fat global variable.
The other thought I have is that it's always easier to make
something a Singleton than to unmake something a Singleton. In my
mind, this is a red flag that needs serious architectural thinking.
Letters to Doctor Java:
Send your questions, comments, and praise to doctorjava@sys-con.com.
Published letters will be edited for length and clarity.