首页 新闻 聚焦 科技 财经 创业 综合 图片 视频

IT界

旗下栏目: 行业 生态 IT界 创新

COMP0008程序代做、代写java程序语言

来源:珠穆朗玛网 发布时间:2020-01-12

COMP0008作业代做、代写java程序语言作业、代写VERSION2实验作业、代做swing作业

COMP0008 Written Java Coursework (2019/20)

NOTE: Your final Moodle submission will consist of a number of parts:

1. Three different versions of the “ConwaysGameOfLife.java” file after different

modifications called: “ConwaysGameOfLife_VERSION1.java”,

“ConwaysGameOfLife_VERSION2.java”,

“ConwaysGameOfLife_VERSION3.java”.

(Thus you should only modify this file and not create other Java files.)

2. A PDF file giving answers to the questions below (given with bold stars). You

can write this description using Word or Latex - as long as you submit a PDF

version in the end.

Getting going ...

Take your favourite Java IDE and install:

Conway’s Game of Life

From the github:

https://github.com/Burke9077/Conway-s-Game-of-Life.git

(You should be familiar with how to do this.)

This is quite a popular version of the game mentioned in a number of websites … but we

are going to analyse its faults and try to improve its structure … in particular focusing on

concurrency.

Build the system, run it and play around with the GUI to get a feel for how it works.

You should take copies of your Java files after each of these tasks to be submitted to

Moodle. [Also this will enable you to roll back to a previous working version if revisions all

go horribly wrong! Although ideally you would be using a revision control system like git.]

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>(InvocationEvent.java:286)

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

at

java.desktop/javax.swing.RepaintManager.scheduleProcessingRunnable(RepaintManager.

java:1485)

at

java.desktop/javax.swing.RepaintManager.addDirtyRegion0(RepaintManager.java:474)

at

java.desktop/javax.swing.RepaintManager.addDirtyRegion(RepaintManager.java:496)

at java.desktop/javax.swing.JComponent.repaint(JComponent.java:4836)

at java.desktop/java.awt.Component.repaint(Component.java:3352)

at ConwaysGameOfLife$GameBoard.run(ConwaysGameOfLife.java:311)

at ConwaysGameOfLife$GameBoard.run(ConwaysGameOfLife.java:314)

… 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 “ConwaysGameOfLife.java”).

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

“ConwaysGameOfLife_VERSION1.java”

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

g.setColor(Color.blue);

g.fillRect(BLOCK_SIZE + (BLOCK_SIZE*newPoint.x), BLOCK_SIZE +

(BLOCK_SIZE*newPoint.y), BLOCK_SIZE, BLOCK_SIZE);

}

} 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

CONCURRENCY EXCEPTION !!!

CONCURRENCY EXCEPTION !!!

CONCURRENCY EXCEPTION !!!

CONCURRENCY EXCEPTION !!!

---

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

CONCURRENCY EXCEPTION !!!

CONCURRENCY EXCEPTION !!!

Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: 47

at ConwaysGameOfLife$GameBoard.run(ConwaysGameOfLife.java:285)

at java.base/java.lang.Thread.run(Thread.java:844)

---

(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

CONCURRENCY EXCEPTION !!!

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException

at

ConwaysGameOfLife$GameBoard.paintComponent(ConwaysGameOfLife.java:229)

at java.desktop/javax.swing.Jcomponent.paint(JComponent.java:1074)

---

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

“ConwaysGameOfLife_VERSION2.java”

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.

*** QUESTION 4: Do five runs and write down the different times your system takes

to do 100,000 cycles of the game of life (these will not all be shown on the screen

due to not having any sleep time in the code).

Now you probably have a multicore processor and the current system is only making use

of a single core since it is running a single thread for all the calculations.

We are going to restructure the code so that a number of threads each do the calculation

of one column of the shared board object. We will used the

Executors.newFixedThreadPool(4) to carry out the tasks (where we change the number of

threads in the pool to see how it affects the overall speed).

Create a FixedThreadPool executor at the top of the GameBoard class with initially 4

threads in the pool.

The restructuring will involve the current run() method creating a new Runnable object,

which you should call “BladeRunner”, for each “i” that it iterates over. Each “BladeRunner”

object will then do the calculation for that column of the boolean[][] gameBoard –

essentially doing the code within the central “i” loop of the current run() method. Each of

these “BladeRunner” objects will be queued on the thread pool so that it executes them.

But how to know when the current run() thread (within the GameBoard) can continue the

calculations for the next cycle of the board? Well … it should create a CountDownLatch

with the number set to the number of columns to calculate (i.e. the number of BladeRunner

objects created). This overall thread will then await on this latch before continuing the next

cycle. Each “BladeRunner” will then do a single countDown() on this latch at the end of its

run method to indicate it has finished. Thus the thread in the GameBoard will only continue

once all the columns have been calculated for the current board.

Your challenge is to work out the detail required to get this architecture to work and also to

worry about concurrency aspects – where might you need to add volatiles or

synchronization? You should be accurate in your analysis and not just add volatiles and

synchronization everywhere!

*** Take a copy of your Java code with 4 threads assigned to the thread pool. Label

the code: “ConwaysGameOfLife_VERSION3.java”

*** QUESTION 5: Experiment with different numbers of threads used in the thread

pool (for example try 1 thread, 2 threads, 4 threads, 6 threads, 8 threads, etc). Each

time record three (or better five) measurements of milliseconds for 100,000 cycles of

the board. Work out average / standard deviation of times and produce a table /

graph to show what might be the optimal number of threads for your system.

*** Please use the Moodle Forum to ask any questions about this coursework ***

*** Upload the three versions of your code and also your answers to Moodle ***

因为专业,所以值得信赖。如有需要,请加QQ:99515681或邮箱:99515681@qq.com 微信:codehelp

  免责声明:珠穆朗玛网对于有关本网站的任何内容、信息或广告,不声明或保证其正确性或可靠性,用户自行承担使用网站信息发布内容的真假风险。
责任编辑:珠穆朗玛网