Java代写 | COMP0008 Written Java Coursework


COMP0008 Written Java Coursework (2019/20)

Task 1: To get you familiar with the code.

Choose the File > Options menu to set the rate of the game at 20 frames per second. Choose the Game > Autofill menu item and select 40% random tiles to fill.

Now start the game running … and wait.

Eventually (after a number of minutes) … it will crash with:

Exception in thread “Thread-0” java.lang.StackOverflowError

at java.desktop/java.awt.event.InvocationEvent.<init>( at java.desktop/java.awt.event.InvocationEvent.<init>(

at java.desktop/javax.swing.RepaintManager.scheduleProcessingRunnable(RepaintManager. java:1485)

at java.desktop/javax.swing.RepaintManager.addDirtyRegion0(

at java.desktop/javax.swing.RepaintManager.addDirtyRegion(

at java.desktop/javax.swing.JComponent.repaint( at java.desktop/java.awt.Component.repaint(

at ConwaysGameOfLife$ at ConwaysGameOfLife$

… and then it repeats this same line hundreds of times !!!

Now you might be tempted to post out a question to “StackOverflow” to resolve this StackOverflowException! But avoid doing this since I think you can fix it yourself with only 3 line of code being changed!

Task 1 is to fix this bug and get familiar with how the code is working. You may not have done any Java Swing programming before … so I’m going to describe how the system generally works below but you may need to look up some further information describing how Swing works.

But before reading below, have a look through the code and try to work out how it is working (it is all in a single file “”).

The system uses the Java Swing toolkit for the graphical elements. The “main” method essentially sets up a “JFrame game = new ConwaysGameOfLife();” which is the main public class in this file. A JFrame is the main graphical interface for the game. The main method then sets up some settings before doing a “game.setVisible(true)” to make the GUI visible.

The constructor of this class sets up all the graphical Swing components of the GUI interface such as menu items, with “action listeners” referencing the class itself. The “actionPerformed” method gets called when a menu item is selected. This looks up the source of different events (such as “ae.getSource().equals(mi_game_play)” and then calls the appropriate method “setGameBeingPlayed(true);”

This method then does:

public void setGameBeingPlayed(boolean isBeingPlayed) {

if (isBeingPlayed) { mi_game_play.setEnabled(false); mi_game_stop.setEnabled(true); game = new Thread(gb_gameBoard); game.start();

} else { mi_game_play.setEnabled(true); mi_game_stop.setEnabled(false); game.interrupt();



The first lines enable and disable particular menu items (mi_game_start and mi_game_stop menu items). But the key lines are the creation of a new “game” thread and starting this. And also calling an interrupt on it to stop this game thread.

The thread is created from the gb_gameBoard which you will see is created at the end of the constructor and then added into the JFrame. This is actually the graphical game board itself which is added onto the JFrame and it gets repainted using its paint() method to draw the current position of “live squares” on the board.

The GameBoard is a private class and it probably has too many responsibilities:

private class GameBoard extends JPanel implements ComponentListener, MouseListener, MouseMotionListener, Runnable {

It extends JPanel which means it is a Swing graphical panel (i.e. draws the board). It also implements different listeners which means it can respond to mouse events and it also implements a Runnable which is the game thread itself. So the GUI event thread may be running through this class, for instance clicking a mouse will cause the “mouseReleased()” method to be called by the GUI event thread. Changing the interface may cause the GUI thread to call the paintComponent() or componentResized() methods. In addition there is the run() method which clearly implements another user threads in this class. Look through this run() method to see what it is doing.

Now what could be causing the StackOverflowError above?

Identify the issue and restructure the code so that it no longer throws this error. This will only require a few lines of code to be changed. Ensure the interrupt mechanism to stop the game still works as well though.

After fixing this bug … you should be able to run the game for a long time without having a StackOverflowError resulting.

*** QUESTION 1: Describe what caused this bug and how you fixed it.

*** Take a copy of your Java code and label it “”

Task 2: Getting into trouble with concurrency.

It should be clear now that there are two threads running through the GameBoard class. A GUI thread which is painting the squares (and also changing them on mouse events) together with changing other aspects of the boards (for instance when resizing the board). Also there is a user thread that is calculating how squares change for the next step in the game. It seems the GameBoard class is responsible for too much and it’s sure to end in disaster!

The GUI thread repaints the board by calling:

public void paintComponent(Graphics g) { within the GameBoard class.

You may notice the lines:

try {

for (Point newPoint : point) {

// Draw new point




} catch (ConcurrentModificationException cme) {}

The catching (and then ignoring) of the “ConcurrentModificationException” sort of indicates that we have a concurrency issue here! Add a “System.out.println(“CONCURRENCY ISSUE !!!”)” into the code to see if we ever get this exception actually being thrown:

} catch (ConcurrentModificationException cme) {System.out.println(“CONCURRENCY EXCEPTION !!!”);}

Running at 20 frames per second with 40% random squares … try changing the board by clicking on it … or resizing the board … minimizing it and maximizing it (causing the repaint method to be called). What you are trying to do is cause the “CONCURRENCY EXCEPTION !!!” message to be displayed. It isn’t easy since it requires the GUI thread and the game thread to collide in terms of accessing or modifying the game squares. But I can produce multiple concurrency exceptions when drawing squares over the board with the mouse button pressed while the game is running:

/usr/lib/jvm/java-1.11.0-openjdk-amd64/bin/java -javaagent:/home/ucackxb/software/idea- IC-183.4588.61/lib/idea_rt.jar=39515:/home/ucackxb/software/idea-IC-183.4588.61/bin – Dfile.encoding=UTF-8 -classpath /home/ucackxb/COURSES/COMP0008/Conway-s- Game-of-Life_version2/out/production/Conway-s-Game-of-Life ConwaysGameOfLife



But you can actually get worse than this. By very quickly decreasing the size of the board while it is being recalculated … you can get the user thread crashing out with an ArrayIndexOutofBoundsException:

/usr/lib/jvm/java-1.11.0-openjdk-amd64/bin/java -javaagent:/home/ucackxb/software/idea- IC-183.4588.61/lib/idea_rt.jar=46389:/home/ucackxb/software/idea-IC-183.4588.61/bin – Dfile.encoding=UTF-8 -classpath /home/ucackxb/COURSES/COMP0008/Conway-s- Game-of-Life_version2/out/production/Conway-s-Game-of-Life ConwaysGameOfLife


Exception in thread “Thread-0” java.lang.ArrayIndexOutOfBoundsException: 47 at ConwaysGameOfLife$ at java.base/

(Make the board the size of the complete screen and start running it with 40% random squares at 20 frames per second. Then press the icon to size it back to its default window size … this almost guarantees it will throw this exception!)

Adjusting the graphics while it is running can also cause the GUI “AWT” thread to crash out with a NullPointer exception which is most likely due to concurrency issues as well (and then the GUI has crashed even though the rest of the program carries on running):

/usr/lib/jvm/java-1.11.0-openjdk-amd64/bin/java -javaagent:/home/ucackxb/software/idea- IC-183.4588.61/lib/idea_rt.jar=32797:/home/ucackxb/software/idea-IC-183.4588.61/bin – Dfile.encoding=UTF-8 -classpath /home/ucackxb/COURSES/COMP0008/Conway-s- Game-of-Life_version2/out/production/Conway-s-Game-of-Life ConwaysGameOfLife


Exception in thread “AWT-EventQueue-0” java.lang.NullPointerException at

ConwaysGameOfLife$GameBoard.paintComponent( at java.desktop/javax.swing.Jcomponent.paint(

For something that looks like it “roughly works” … it’s amazing how fragile it really is due to not considering concurrency issues properly! (In fact putting in code that ignores concurrency issues!)

Your second task it to fix these concurrency issues! Actually it may seem daunting but it really comes down to identifying the shared state that is being modified by both threads and ensuring that it is being operated on safely.

It may be useful to understand how ConcurrentModificationExceptions arise. The Brian Goetz book explains this in Section 5.1.2 on page 82 (although it would be worthwhile reading from the start of Chapter 5 on page 79 to Section 5.3 Blocking Queues and the producer-consumer pattern on page 87 to get context for this and also to understand the CopyOnWriteArrayList in Section 5.2.3 which we will be using).

It may also be useful to read Chapter 9 GUI Applications (pages 189-202) of the Brian Goetz book to get familiar with both Swing GUIs and how threads work in the GUI subsystem.

Change the ArrayList used currently for the “state” of the GameBoard to using the concurrent CopyOnWriteArrayList object. Can you now make the system crash by adding points and resizing the window?

*** QUESTION 2: Explain what is the key difference in how the CopyOnWriteArrayList behaves compared to a normal ArrayList which has probably made all these concurrency issues disappear (be specific about how a particular mechanism used in the code works differently with these two classes).

*** QUESTION 3: What could be a disadvantage of using CopyOnWriteArrayList here instead of a normal Arraylist? (Assuming we weren’t worried about the concurrency issues!)

*** Take a copy of your Java code and label it “”

Task 3: Speed it up challenge!

This part is more challenging and the instructions are less detailed. So you will have to work out how certain aspects need to be structured yourself and also worry about whether your code is thread safe.

We first want to calculate the time it takes to do 100,000 cycles of the board without any sleeping involved.

  1. Comment out the sleep statement in the run() method so it runs at maximum speed.
  2. Change the structure within the run() method so that it does 100,000 cycles of the board and then finishes automatically.
  3. Add “Date” objects (or similar) so that you can print out the time it takes to do the 100,000 cycles in milliseconds.


本网站支持淘宝 支付宝 微信支付  paypal等等交易。如果不放心可以用淘宝交易!

E-mail: [email protected]  微信:itcsdx