I wrote this java code with synchronized and busy waiting but I don't know why it doesn't work right! for example I get this output
produced:6
produced:7
consumed:0
consumed:0
how 6 and 7 are produced but 0 is consumed ??? I don't know what's wrong with it,please help me ,here is my code:
package conper;
import java.util.*;
import java.util.concurrent.TimeUnit;
class Queue<Integer> {
int items=0;
int q=0;
public int[] array= new int[10];
Queue(int i) {
}
public boolean isEmpty(){
if (this.q > 0)
{
return false ;
}else{
return true ;}
}
public boolean isFull(){
if (this.q > 10)
{
return true ;
}else{
return false ;
}
}
public int size(){
return items;
}
public synchronized void add(int x){
if(!isFull()){
array[++q]=x;
}
}
public synchronized void remove(int x){
if(!isEmpty()){
array[--q]=x;
}
}
}
class Producer implements Runnable {
private Random random = new Random();
private Queue<Integer> queue;
private boolean working = true;
public Producer(Queue<Integer> q) {
queue = q;
}
public void run() {
int product=0;
int loop = random.nextInt(10) + 20;
for (int i = 0; i < loop; i++) {
double h = Math.pow(2, Math.E * i);
}
while(working){
product = produce();
if(!queue.isFull() ){
break;
}
}
queue.add(product);
System.out.println("produced:"+product);
}
public void stop() {
working = false;
}
private int produce() {
int result = 0;
int loop = random.nextInt(10) + 20;
for (int i = 0; i < loop; i++) {
double h = Math.pow(2, Math.E * i);
}
result = random.nextInt(10);
return result;
}
}
class Consumer implements Runnable {
private Random rnd = new Random();
private Queue<Integer> queue;
private boolean working = true;
public Consumer(Queue<Integer> q) {
queue = q;
}
public void run() {
int product = 0;
while(working){
if(!queue.isEmpty())
break;
}
queue.remove(product);
System.out.println("consumed:"+product);
consume(product);
}
public void stop() {
working = false;
}
public void consume(int product) {
int loop = rnd.nextInt(10000) + 2000;
for (int i = 0; i < loop; i++) {
double h = Math.pow(2, Math.E * i);
}
}
}
public class Main {
public static void main(String[] args) {
Queue<Integer> queue = new Queue<Integer>(5);
Producer p1 = new Producer(queue);
Producer p2 = new Producer(queue);
Consumer c1 = new Consumer(queue);
Consumer c2 = new Consumer(queue);
Thread pt1 = new Thread(p1);
Thread pt2 = new Thread(p2);
Thread ct1 = new Thread(c1);
Thread ct2 = new Thread(c2);
pt1.start();
pt2.start();
ct1.start();
ct2.start();
try {
TimeUnit.MILLISECONDS.sleep(200);
p1.stop();
p2.stop();
c1.stop();
c2.stop();
}
catch (Exception e) {
return;
}
}
}
any suggestion?
Your consumer code reads
int product = 0;
// code which doesn't change "product"
System.out.println("consumed:"+product);
I suggest you need a remove() method which returns the value from the queue instead of being passed a value.
I also suggest you get the code to work in one thread before attempting to use in multiple threads.
Related
I have 2 test cases, while the first one is failed and the second one can successed.
The only difference code is method incr of class Incr.
Why?
public class ReentrantSpinLockTest {
private final Incr incr = new Incr();
#Test
public void lock() throws InterruptedException {
int n = 50;
int inner_loop = 100_000;
CountDownLatch boot = new CountDownLatch(n);
CountDownLatch complete = new CountDownLatch(n);
for (int i = 0; i < n; ++i) {
new Thread(() -> {
try {
boot.await();
for (int k = 0; k < inner_loop; ++k) {
incr.incr();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
complete.countDown();
}
}).start();
boot.countDown();
}
complete.await();
int expect = n * inner_loop;
int actual = incr.getI();
assert expect == actual : String.format("expect %d actual %d", expect, actual);
}
}
The successful Incr:
public class Incr {
private final ReentrantLock lock = new ReentrantLock();
private volatile int i;
// only this diff
public void incr() {
lock.lock();
lock.lock();
i++;
lock.unlock();
lock.unlock();
}
public int getI() {
return i;
}
}
The failed Incr:
public class Incr {
private final ReentrantLock lock = new ReentrantLock();
private volatile int i;
public void incr() {
int k = Math.abs(new Random().nextInt() % 5);
for (int t = 0; t < k; ++t) {
lock.lock();
}
i++;
for (int t = 0; t < k; ++t) {
lock.unlock();
}
}
public int getI() {
return i;
}
}
I want to calculate sum of 2D array with multithreading. But I can't get correct result and programm can't end for some reason.
MatrixService devides task to threads and contains result. (methods getSumma() and setSumma(int summa) are taken from Herbert Schildt)
public class MatrixService {
private boolean valueGet = false;
private int summa;
public int sum(int[][] matrix, int nThreads) {
for (int i = 0; i < nThreads; i++) {
new ColumnSummator(this, matrix, nThreads, i);
}
return summa;
}
public synchronized int getSumma() {
while (valueGet) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
valueGet = true;
notify();
return summa;
}
public synchronized void setSumma(int summa) {
while (!valueGet) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
this.summa = summa;
valueGet = false;
notify();
}
}
ColumnSummator choose columns for sum which this Thread should calculate
import java.util.ArrayList;
import java.util.List;
public class ColumnSummator implements Runnable {
private int summOfColumns;
private final MatrixService matrixService;
private final int[][] matrix;
private final List<Integer> numberColumnsForCount = new ArrayList<>();
public ColumnSummator(MatrixService matrixService, int[][] matrix, int nThreads, int columnSummatorId) {
this.matrixService = matrixService;
this.matrix = matrix;
for (int i = 0; i < matrix[0].length; i++) {
if (i % nThreads == columnSummatorId) {
numberColumnsForCount.add(i);
}
}
new Thread(this).start();
}
#Override
public void run() {
for (int i = 0; i < matrix[0].length; i++) {
if (numberColumnsForCount.contains(i)) {
for (int j = 0; j < matrix.length; j++) {
summOfColumns += matrix[j][i];
}
}
}
matrixService.setSumma(matrixService.getSumma() + summOfColumns);
}
}
And inside main:
public static void main(String[] args) {
MatrixService matrixService = new MatrixService();
int[][] matrix = new int[10][10];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
matrix[i][j] = (i + 1) * (j + 1);
}
}
int summa = matrixService.sum(matrix, 6);
System.out.println(summa);
}
I am not an expert on java and have run into an issue on my Snake Game. I have created a class called GameManager:
public class GameManager {
private GameObject board[][];
private int xR;
private int yR;
public Snake snk;
private Food food;
public GameManager (String fileName) {
BufferedReader fileInput = null;
try {
fileInput = new BufferedReader(new FileReader(fileName));
Scanner fileScanner = new Scanner(fileInput);
int rows = fileScanner.nextInt();
int cols = fileScanner.nextInt();
board = new GameObject[rows][cols];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
board[row][col] = new Empty();
}
}
while(fileScanner.hasNext()) {
fileScanner.nextLine();
int xStart = fileScanner.nextInt();
int yStart = fileScanner.nextInt();
int xEnd = fileScanner.nextInt();
int yEnd = fileScanner.nextInt();
addWall(xStart, yStart, xEnd, yEnd);
}
addGameObject(snk);
addGameObject(food);
fileScanner.close();
} catch(IOException e) {
e.printStackTrace();
} finally {
try {
if(fileInput != null) {fileInput.close();}
} catch(IOException e) {
e.printStackTrace();
}
}
}
public void newRandomXY() {
Random r = new Random(0);
this.xR = r.nextInt(board.length);
this.yR = r.nextInt(board.length);
}
public void addGameObject(GameObject s) {
newRandomXY();
while(board[xR][yR].isOccupied()) {
newRandomXY();
}
if(s instanceof Snake) {
s = new Snake(xR, yR);
board[xR][yR] = s;
} else if(s instanceof Food) {
s = new Food(xR, yR);
board[xR][yR] = s;
}
}
public void addWall(int xStart, int yStart, int xEnd, int yEnd) {
for(int x = xStart; x <= xEnd; x++) {
for(int y = yStart; y <= yEnd; y++) {
board[x][y] = new Wall();
}
}
}
#Override
public String toString() {
String ret = "";
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
ret += board[row][col].toString();
}
ret += "\n";
}
return ret;
}
}
Now the issue I'm having is that whenever I try to print a string version of this board on my cmd, the program just hangs and I have to hard close the cmd. I have been messing around with some of the code and I have been able to fix the program just crashing, but I haven't been able to figure why its all not printing out.
Here is my Snake Class (Note: I also have some other methods in this class that I am not using at the moment, so I don't think they are the issue):
public class Snake extends GameObject {
private Point head;
private Deque<Point> snakeBody;
private int lenght = 0;
private String direction = "UP";
public Snake(int x, int y) {
this.head = super.newCell(x, y);
this.snakeBody = new ArrayDeque<Point>();
this.snakeBody.push(head);
}
and my toString of Snake:
public String toString(Deque<Point> s) {
String str = "";
for(Point p : s) {
String snk = p.toString();
snk = "S";
str += snk;
}
return str;
}
Here's my Food Class:
public class Food extends GameObject {
private Point foodLoc;
public Food(int x, int y) {
this.foodLoc = new Point(x, y);
}
public Point getLocation() {
return foodLoc.getLocation();
}
public String toString() {
return "F";
}
}
and here is my GameObject Class:
import java.awt.Point;
public class GameObject {
public final int CELL_SIZE = 1;
public Point newCell(int x, int y) {
return new Point(x, y);
}
public boolean isOccupied() {
return true;
}
public boolean isOccupied(Point p, Point o) {
boolean flag = false;
if(p.getLocation().equals(o.getLocation())) {
flag = true;
} else {
flag = false;
}
return flag;
}
}
I have a good feeling that my toString method in Snake is completely wrong, but I don't necessarily understand how to fix it and why my other toString methods don't work. I have looked around the forums to see if I could find and answer, but I couldn't find anything for this.
The problem is that you're trying to print an array of type gameObject, but that object does not have a .toString operator, so it's always going to return null.
I'm guessing that you want to represent the cells as either empty or occupied, or perhaps even further by having food, but you'd need a .toString in that class to define what you want returned in whatever given scenario.
First of all there is a lot of code because i really don't know where my issue is, I do apologise!
I'm making a program that solves a varying size puzzle for eg (3x3 with 0-8) The zero represents a blank tile the objective is to move the the blank tile around until the goal state is reached. At the moment I am using Depth First Search to solve the puzzle. Netbeans returns a 'OutOfMemory' error when i run the program however if I change the goal state so it only requires one move to complete it displays the solution. Below is my code, I've only added some of the classes because I don't want this post being ridiculously long. Please let me know if you require the other classes
EDIT: Inserted wrong code for board class
Depth First Search Class
package npuzzle;
import java.util.ArrayList;
import java.util.Stack;
public class DFSearch {
public static void search(int[][] initial, int[][] goal, int rows, int columns)
{
Board board = new Board(initial, goal, rows, columns, "");
Node root = new Node(board);
Stack<Node> stack = new Stack<Node>();
stack.add(root);
performSearch(stack, board);
}
public static void performSearch(Stack<Node> s, Board board)
{
int searchCount = 1;
while (!s.isEmpty())
{
Node tNode = (Node) s.pop();
//if not goal state
if (!tNode.getCurrentState().isGoalState())
{
ArrayList<State> tChildren = tNode.getCurrentState().gChildren();
for (int i = 0; i < tChildren.size(); i++)
{
Node newNode = new Node(tNode, tChildren.get(i), tNode.getGCost() + tChildren.get(i).findCost(), 0);
if(!isRepeatedState(newNode))
{
s.add(newNode);
}
}
searchCount++;
}
else
{
tNode.getCurrentState().printState();
System.exit(0);
//PRINTING OF DIRECTIONS
}
}
System.out.println("Error! No solution found!");
}
private static boolean isRepeatedState(Node c)
{
boolean returnVal = false;
Node checkNode = c;
while(c.getParent() != null && !returnVal)
{
if (c.getParent().getCurrentState().equals(checkNode.getCurrentState()))
{
returnVal = true;
}
c = c.getParent();
}
return returnVal;
}
}
Board Class
package npuzzle;
import java.util.ArrayList;
import java.util.Arrays;
public class Board implements State
{
private int PUZZLE_SIZE = 0;
private int outOfPlace = 0;
private int rows;
private int columns;
private int[][] GOAL;
private int[][] currentBoard;
private String directions = "";
public Board(int[][] initial, int[][] goal, int N, int M, String direction)
{
currentBoard = initial;
GOAL = goal;
rows = N;
columns = M;
PUZZLE_SIZE = rows*columns;
directions = direction;
setOutOfPlace();
}
#Override
public boolean isGoalState() {
if (Arrays.deepEquals(currentBoard, GOAL))
{
return true;
}
return false;
}
#Override
public ArrayList<State> gChildren() {
ArrayList<State> children = new ArrayList<State>();
int[] blanktile = getBlankTile();
int[] newblanktile = Arrays.copyOf(blanktile, blanktile.length);
if (blanktile[0] != 0) {
newblanktile[0]--;
Swap(newblanktile, blanktile, children, "up");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
if (blanktile[1] != 0) {
newblanktile[1]--;
Swap(newblanktile, blanktile, children, "left");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
if (blanktile[0] != (this.rows - 1)) {
newblanktile[0]++;
Swap(newblanktile, blanktile, children, "down");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
if (blanktile[1] != (this.columns - 1)) {
newblanktile[1]++;
Swap(newblanktile, blanktile, children, "right");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
return children;
}
#Override
public double findCost() {
return 1;
}
#Override
public void printState() {
System.out.println(directions);
}
#Override
public boolean equals(State s) {
if (Arrays.deepEquals(currentBoard, ((Board) s).getCurrentBoard()))
{
return true;
}
else
return false;
}
private void setOutOfPlace() {
int i = 0;
int j = -1;
do
{
if (j == (columns - 1)) {j = 0; i++;}
else {j++;}
if (currentBoard[i][j] != GOAL[i][j])
{
outOfPlace++;
}
} while (((i+1)*(j+1)) < PUZZLE_SIZE);
}
private int[] getBlankTile()
{
int i = 0;
int j = -1;
int[] blanktile = {0,0};
do
{
if (j == (columns - 1)) {j = 0; i++;}
else {j++;}
if (currentBoard[i][j] == 0) {
blanktile[0] = i;
blanktile[1] = j;
}
} while (((i+1)*(j+1)) < PUZZLE_SIZE);
return blanktile;
}
public int getOutOfPlace()
{
return outOfPlace;
}
private int[][] copyBoard(int[][] state)
{
int[][] returnArray = new int[rows][columns];
for (int i = 0, j = 0; i*j < PUZZLE_SIZE; i++, j++)
{
returnArray[i] = Arrays.copyOf(state[i], state[i].length);
}
return returnArray;
}
private void Swap(int[] nbt, int[] bt, ArrayList<State> children, String direction) {
int[][] cpy = copyBoard(currentBoard);
int temp = cpy[nbt[0]][nbt[1]];
cpy[nbt[0]][nbt[1]] = currentBoard[bt[0]][bt[1]];
cpy[bt[0]][bt[1]] = temp;
children.add(new Board(cpy, this.getGOAL(), this.getRows(), this.getColumns(), (this.getDirections() + direction + ", ")));
}
public int getPUZZLE_SIZE() {
return PUZZLE_SIZE;
}
public int getRows() {
return rows;
}
public int getColumns() {
return columns;
}
public int[][] getGOAL() {
return GOAL;
}
public int[][] getCurrentBoard()
{
return currentBoard;
}
public String getDirections()
{
return directions;
}
}
So I'm trying to run my pacman project as a jar(also tried runnable) and I just get the error message you see in the title. It runs perfectly fine in eclipse/netbeans, but whilst cleaning/building i see the warnings:
Note: C:\Users\Lucas\Documents\Eclipse\PackMan\src\game\packman\GameData.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
The main class is correct and assigned. Does anybody know what I'm doing wrong?
Here is my GameData class
public class GameData {
int mazeNo;
CopyOnWriteArrayList<Position> pills;
CopyOnWriteArrayList<Position> powerPills;
public MoverInfo packman;
public GhostInfo[] ghostInfos = new GhostInfo[4];
public int score;
Maze[] mazes;
boolean dead = false;
boolean win = false;
public GameData() {
mazes = new Maze[4];
// load mazes information
for (int m=0; m<4; m++) {
mazes[m] = new Maze(m);
}
setMaze(mazeNo);
}
private void setMaze(int m) {
packman = new MoverInfo(mazes[m].packmanPos);
for (int g=0; g<4; g++) {
ghostInfos[g] = new GhostInfo(mazes[m].ghostPos);
}
pills = new CopyOnWriteArrayList((List<Position>)(mazes[m].pills.clone()));
powerPills = new CopyOnWriteArrayList((List<Position>)(mazes[m].powerPills.clone()));
}
public void movePackMan(int reqDir) {
if (move(reqDir, packman)) {
packman.curDir = reqDir;
} else {
move(packman.curDir, packman);
}
}
private int wrap(int value, int incre, int max) {
return (value+max+incre)%max;
}
private boolean move(int reqDir, MoverInfo info) {
// current position of packman is (row, column)
int row = info.pos.row;
int column = info.pos.column;
int rows = mazes[mazeNo].rows;
int columns = mazes[mazeNo].columns;
int nrow = wrap(row, MoverInfo.DROW[reqDir], rows);
int ncol = wrap(column, MoverInfo.DCOL[reqDir], columns);
if (mazes[mazeNo].charAt(nrow, ncol) != '0') {
info.pos.row = nrow;
info.pos.column = ncol;
return true;
}
return false;
}
public void update() {
if (pills.contains(packman.pos)) {
pills.remove(packman.pos);
score += 5;
} else if (powerPills.contains(packman.pos)) {
powerPills.remove(packman.pos);
score += 50;
for (GhostInfo g:ghostInfos) {
g.edibleCountDown = 500;
}
}
for (GhostInfo g:ghostInfos) {
if (g.edibleCountDown > 0) {
if (touching(g.pos, packman.pos)) {
// eat the ghost and reset
score += 100;
g.curDir = g.reqDir = MoverInfo.LEFT;
g.pos.row = mazes[mazeNo].ghostPos.row;
g.pos.column = mazes[mazeNo].ghostPos.column;
g.edibleCountDown = 0;
}
g.edibleCountDown--;
} else {
if (touching(g.pos, packman.pos)) {
dead = true;
}
}
}
// level is cleared
if (pills.isEmpty() && powerPills.isEmpty()) {
mazeNo++;
if (mazeNo < 4) {
setMaze(mazeNo);
} else if (mazeNo == 5) {
win = true;
} else {
// game over
dead = true;
}
}
}
private boolean touching(Position a, Position b) {
return Math.abs(a.row-b.row) + Math.abs(a.column-b.column) < 3;
}
public void moveGhosts(int[] reqDirs) {
for (int i=0; i<4; i++) {
GhostInfo info = ghostInfos[i];
info.reqDir = reqDirs[i];
if (move(info.reqDir, info)) {
info.curDir = info.reqDir;
} else {
move(info.curDir, info);
}
}
}
public int getWidth() {
return mazes[mazeNo].width;
}
public int getHeight() {
return mazes[mazeNo].height;
}
public List<Integer> getPossibleDirs(Position pos) {
List<Integer> list = new ArrayList<>();
for (int d=0; d<4;d++) {
Position npos = getNextPositionInDir(pos, d);
if (mazes[mazeNo].charAt(npos.row, npos.column) != '0') {
list.add(d);
}
}
return list;
}
private Position getNextPositionInDir(Position pos, int d) {
int nrow = wrap(pos.row, MoverInfo.DROW[d], mazes[mazeNo].rows);
int ncol = wrap(pos.column, MoverInfo.DCOL[d], mazes[mazeNo].columns);
return new Position(nrow, ncol);
}
}