JWS Task 4: Multithreading and Conway’s Life

R-pentomino
Write Endpoint Publisher that uses threads executer to support multithreading and simple graphical end-user client.
Use basic implementation of Conway’s Game of Life as web method.
Example Solution
Service Implementation Bean
package com.fuzilaga.jws.conwayslife;
import javax.jws.WebService;
@WebService(endpointInterface = "com.fuzilaga.jws.conwayslife.ConwaysLifeService")
public class ConwaysLifeServiceImpl implements ConwaysLifeService
{
private int[][] map;
@Override
public int[][] nextGeneration()
{
if (null == map)
{
return null;
}
int[][] newMap = new int[map.length][map.length];
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map.length; j++)
{
int countNeighbours = countNeighbours(i, j);
if (countNeighbours < 2 || countNeighbours > 3)
{
newMap[i][j] = 0;
}
else if (countNeighbours == 3)
{
newMap[i][j] = 1;
}
else
{
newMap[i][j] = map[i][j];
}
}
}
map = newMap;
return map;
}
@Override
public void createGeneration(int[][] map)
{
this.map = map;
}
private int countNeighbours(int i, int j)
{
int count = 0;
int[][] neighbours = new int[][] { { i - 1, j - 1 }, { i, j - 1 }, { i + 1, j - 1 }, { i - 1, j }, { i + 1, j }, { i - 1, j + 1 }, { i, j + 1 }, { i + 1, j + 1 } };
for (int k = 0; k < neighbours.length; k++)
{
int x = neighbours[k][0];
int y = neighbours[k][1];
if (x >= 0 && y >= 0 && x < map.length && y < map.length)
{
count += map[x][y];
}
}
return count;
}
}
Service Publisher
package com.fuzilaga.jws.conwayslife;
import java.util.concurrent.Executors;
import javax.xml.ws.Endpoint;
public class ConwaysLifeServicePublisher
{
public static void main(String args[])
{
Endpoint endpoint = Endpoint.create(new ConwaysLifeServiceImpl());
endpoint.setExecutor(Executors.newFixedThreadPool(4));
endpoint.publish("http://localhost:8880/conway");
}
}
Service Client
package com.fuzilaga.jws.conwayslife;
import java.awt.Color;
import java.awt.Graphics;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class ConwaysLifeClient extends JPanel implements Runnable
{
private int width = 310, height = 335, areaWidth = 30, areaHeight = 30;
private int[][] map = new int[areaWidth][areaHeight];
private ConwaysLifeService conway;
public void paintComponent(Graphics g)
{
g.clearRect(0, 0, width, height);
g.setColor(Color.BLUE);
for (int i = 0; i < areaWidth; i++)
{
for (int j = 0; j < areaHeight; j++)
{
if (map[i][j] == 1)
{
g.fillOval(i * 10, j * 10, 7, 7);
}
else
{
g.drawOval(i * 10, j * 10, 7, 7);
}
}
}
}
public void run()
{
try
{
while (null != conway)
{
Thread.sleep(500);
map = conway.nextGeneration();
repaint();
}
} catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String args[]) throws Exception
{
ConwaysLifeClient client = new ConwaysLifeClient();
client.map[15][14] = client.map[15][15] = client.map[15][16] = client.map[14][15] = client.map[16][16] = 1;
JFrame frame = new JFrame("Conway's Life");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(client);
frame.setSize(client.width, client.height);
frame.setVisible(true);
URL url = new URL("http://localhost:8880/conway");
QName qname = new QName("http://conwayslife.jws.fuzilaga.com/", "ConwaysLifeServiceImplService");
Service service = Service.create(url, qname);
client.conway = service.getPort(ConwaysLifeService.class);
client.conway.createGeneration(client.map); // set initial map
Thread t = new Thread(client);
t.start();
}
}
Screenshot of four simultaneously running clients:
NOTE: Full source and instructions on how to run locally can be found here.