Hi guys,

I have this assignment to do:

Synchronize access to the instance variable, accBalance. Because accBalance is a double and not an object, it cannot be used as the monitor. Use synchronized methods or synchronized blocks of code, as appropriate. Simultaniously test two threads. Because the threads can complete too quickly to determine if they are interfering with each other, delay the adding of a deposit by inserting the following code within the synchronized block or method:

try
{
      Thread.currentThread().sleep(10000);
}
catch(InterruptedException e) {}

I've been strugling with this thing for weeks now, I just don't get Synchronization. I've tried reading up on it but it just doesn't help me. I'm not asking anybody to do this for me, I just want some advice, a push in the right direction etc.. This is the code that I have to Synchronize:

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.text.DecimalFormat;

public class SyncBank extends HttpServlet
{
	// Create Class Variable
	DecimalFormat myFormat = new DecimalFormat("$#,000.00");
	double accBalance = 0.00;

	public void doGet(HttpServletRequest req,HttpServletResponse res)
						throws ServletException, IOException
	{
		doPost(req,res);
	}

	public void doPost(HttpServletRequest req,HttpServletResponse res)
						throws ServletException, IOException
	{

		//Set MIME type of content returned to browser
		res.setContentType("text/html");
		PrintWriter out = res.getWriter();

		//Starts outputting the HTML Form
		out.println("<html><head>" +
					"<title>Online Bank Simulator</title>" +
					"</head><body>" +
					"<hr color=\"#808000\">" +
					"<center><h1>Banking Simulation</h1></center>" +
					"<form method=\"POST\" action=\"../servlet/HTMLBank\">" +
					"<center>Amount: <input type=\"text\" name=\"Amount\" size=\"20\"></center>");

		//Decides which action to take
		String action = req.getParameter("act");

		if(action != null)
		{
			if(action.equals("Deposit"))
			{
				double amount;
				String strAmount = req.getParameter("Amount");
				amount = Double.parseDouble(strAmount);

				if(amount <= 0.00)
				{
					out.println("<h2>Error: The amount is either null or a minus</h2>");
				}
				else
				{
					accBalance = accBalance + amount;
					out.println("<br><center>Balance:"+myFormat.format(accBalance)+" </center> <br>");
				}
			}
			else if(action.equals("Withdraw"))
			{
				double amount;
				String strAmount = req.getParameter("Amount");
				amount = Double.parseDouble(strAmount);

				if(amount <= 0.00)
				{
					out.println("<h2>Error: The amount is either null or a minus</h2>");
				}
				else
				{
					accBalance = accBalance - amount;
					out.println("<br><center>Balance:"+myFormat.format(accBalance)+" </center> <br>");
				}
			}
			else if(action.equals("Balance"))
			{
				out.println("<br><center>Balance:"+myFormat.format(accBalance)+" </center> <br>");
			}
			else
			{
				out.println("<br><center>Balance:"+myFormat.format(accBalance)+" </center> <br>");
			}
		}
		else
		{
			out.println("<br><center>Balance:"+myFormat.format(accBalance)+" </center> <br>");
		}


		//Outputs rest of HTML
		out.println("<table width=\"35%\" align=\"center\">" +
					"<tr><td width=\"33%\" align=\"center\">" +
					"<input type=\"submit\" name=\"act\" value=\"Deposit\">" +
					"</td>" +
					"<td width=\"33%\" align=\"center\">" +
					"<input type=\"submit\" name=\"act\" value=\"Withdraw\">" +
					"</td>" +
					"<td width=\"33%\" align=\"center\">" +
					"<input type=\"submit\" name=\"act\" value=\"Balance\">" +
					"</td></tr>" +
					"</table><br>" +
					"</form>" +
					"<hr color=\"#80800\">" +
					"</body></html>");

	}
}

Thanks so much for looking at this..

The servlet container creates a single instance of the servlet and reuses the same for every request. This has the implication that your instance variables in your Servlet would be shared across all reqests thereby resulting in the `accBalance` being shared across all accounts. You can of course synchronize all the actions which operate on the `accBalance` variable but that would effectively mean only a "single" client would be able to work with the `accBalance` variable thereby killing any chances of concurrent requests being processed. The solution? Use session variables for maintaining balance for each "account"/"client".

public class MyServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        String action = getAction(req);
        double amt = Double.parseDouble(req.getParameter("amt"));
        HttpSession session = req.getSession(true);
        synchronized(session) {
            Double oldAmt = session.getAttribute("accBalance");
            Double newAmt = // add old amt and amt
            session.putAttribute("accBalance", newAmt);
        }
    }
}

Also, delegate your view rendering to a JSP instead of embedding the HTML rendering in your servlet; any more complicated view logic and your servlet would become unmaintainable. Read up the official servlet/JSP tutorial; http://download.oracle.com/javaee/1.4/tutorial/doc/ (assuming you are using java ee 1.4)

More recommended reading:
http://stackoverflow.com/questions/2183974/difference-each-instance-of-servlet-and-each-thread-of-servlet-in-servlets
http://www.velocityreviews.com/forums/t388103-how-servlet-works.html

Thank you so much for your input!
The information you gave is great, although where you said:
" You can of course synchronize all the actions which operate on the `accBalance` variable but that would effectively mean only a "single" client would be able to work with the `accBalance` variable thereby killing any chances of concurrent requests being processed"

I think this is exaclty what my college wants me to do, not very practical or very effective, but it's just to teach us how synchronization works etc etc. If I were to do this then, would I just make the doPost method synchronized and the rest will fall into place or should i make a synchronized(){....} section of code somewhere INSEIDE the doPost method?

Actualy the code section you posted made alot more sense.. Maybe I should just do it that way..

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.