I created a stack class like this. Some times it runs and sometimes it will through ArrayIndexOutofBoundException. What's wrong in threading? Couldn't understand please help.
public class StackImpl<E> implements Stack<E>{
private E[] stackArray;
private int topOfStack;
public StackImpl(int size) {
stackArray = (E[]) new Object[size];
topOfStack = -1;
}
public synchronized void push(E e) {
while (isFull()) {
try {
System.out.println("stack is full cannot add " + e);
wait();
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
stackArray[++topOfStack] = e;
System.out
.println(Thread.currentThread() + " :notifying after pushing");
notify();
}
public boolean isEmpty() {
return topOfStack == 0;
}
public synchronized E pop() {
while (isEmpty()) {
try {
System.out.println("stack is empty cannot pop ");
wait();
} catch (InterruptedException e) {
}
}
System.out.println(topOfStack);
E element = stackArray[topOfStack];
stackArray[topOfStack--] = null;
System.out.println(Thread.currentThread() + " notifying after popping");
notify();
return element;
}
public boolean isFull() {
return topOfStack >= stackArray.length-1;
}
public static void main(String[] args) {
final Stack<Integer> stack = new StackImpl<Integer>(10);
(new Thread("Pusher") {
public void run() {
while (true) {
stack.push(10);
}
}
}).start();
(new Thread("Popper") {
public void run() {
while (true) {
stack.pop();
}
}
}).start();
}
}
You set
topOfStack = -1;
in the constructor of StackImpl, yet your isEmpty method checks for 0:
public boolean isEmpty() {
return topOfStack == 0;
}
So the while loop will fall through on first pop, if the pusher hasn't added any values yet:
public synchronized E pop() {
while (isEmpty()) {
try {
System.out.println("stack is empty cannot pop ");
wait();
} catch (InterruptedException e) {
}
}
Set the topOfStack to 0 on the constructor and it should work.
Edit: come to think of it, instead change the isEmpty -method to return topOfStack < 0;, and leave the topOfStack = -1; in your constructor... otherwise element in index 0 is never popped.
Related
I integrated code to sonarqube for quality code and set method complexity is 4.
Please help me to reduce this for loop complexity to 4
for (int i = 1; i <= retryCount + count; i++) {
try {
if (cat!= null)
grps = cat.getAllGroups(category);
flag = true;
} catch (Exception e) {
if (i >= retryCount + count) {
throw new MyException(new Fault(1009,
new Object[] { e.getMessage() }));
} else {
if (e.getMessage().contains("No Records Found")) {
break;
} else {
String status = handleIOAutomationException(ctx, e);
if (status.equalsIgnoreCase("none")) {
throw new MyException(new Fault(1009,
new Object[] { e.getMessage() }));
} else if (status.equalsIgnoreCase("some")) {
}
}
}
}
if (flag) {
break;
}
}
Try to extract your logic into its own sub methods and try make these shorter. You should also try to make your identifiers more readable.
public void method() {
...
int maxLoops = retryCount + count;
for (int i = 1; i <= maxLoops; i++) {
if (tryToGetAllGroups(maxLoops, i))
break;
}
}
private boolean tryToGetAllGroups(int maxLoops, int i) throws MyException {
try {
if (cat != null)
grps = cat.getAllGroups(category);
return true;
} catch (Exception e) { // you should make Exception more specific!
if (i >= maxLoops) {
return throwFinalException(e);
} else {
if (tryToGetCat(e)) return true;
}
}
return false;
}
private boolean tryToGetCat(Exception e) throws MyException {
if (e.getMessage().contains("No Records Found")) {
return true;
} else {
String status = handleIOAutomationException(ctx, e);
if (status.equalsIgnoreCase("none")) {
throwFinalException(e);
} else if (status.equalsIgnoreCase("some")) {
// try to get cat here
}
}
return false;
}
private boolean throwFinalException(Exception e) throws MyException {
throw new MyException(new Fault(1009,
new Object[]{e.getMessage()}));
}
new to multithreading. I wrote this program which should be a solution to the producer-consumer problem. The problem is that both a producer and a consumer end up in the waiting state. What seems to be wrong? (And everything else what is wrong ^_^) Thanks in advance.
Main class:
package producer.consumer2;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Buffer<Integer> bf = new Buffer<>(10);
Producer prod = new Producer(bf);
Consumer cons = new Consumer(bf);
prod.setConsumer(cons);
cons.setProducer(prod);
new Thread(prod).start();
new Thread(cons).start();
if(quitInput()) {
prod.terminate();
cons.terminate();
}
}
private static boolean quitInput() {
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
do {
if(line.toLowerCase().equals("q") || line.toLowerCase().equals("quit")) {
sc.close();
return true;
}
line = sc.nextLine();
} while(true);
}
}
Buffer class:
package producer.consumer2;
import java.util.ArrayList;
public class Buffer<E> {
private final int MAX_LENGTH;
private ArrayList<E> values;
public Buffer(int length){
MAX_LENGTH = length;
values = new ArrayList<E>(length);
}
public synchronized void add(E e) {
if(values.size() < MAX_LENGTH) {
values.add(e);
System.out.println(values);
} else {
throw new RuntimeException("Buffer is full at the moment.");
}
}
public synchronized boolean isEmpty() {
return values.size() == 0;
}
public synchronized boolean isFull() {
return values.size() >= MAX_LENGTH ? true : false;
}
public synchronized E remove(int index) {
E val = values.remove(index);
System.out.println(values);
return val;
}
}
Consumer class:
package producer.consumer2;
public class Consumer implements Runnable {
private final Buffer<Integer> bf;
private volatile boolean running = true;
private Producer prod;
public Consumer(Buffer<Integer> bf) {
this.bf = bf;
}
public void setProducer(Producer prod) {
this.prod = prod;
}
#Override
public void run() {
int sum = 0;
int counter = 0;
while (running) {
if (bf.isEmpty()) {
if (prod != null) {
synchronized (prod) {
prod.notify();
}
}
myWait(0);
} else {
sum += bf.remove(0);
counter++;
}
}
System.out.println("for first " + counter + " nums an avg = " + ((double) sum / counter));
}
private void myWait(long millisecs) {
System.out.println("consumer is waiting.");
try {
synchronized (this) {
this.wait(millisecs);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("consumer is NOT waiting.");
}
public void terminate() {
this.running = false;
}
}
Producer class:
package producer.consumer2;
public class Producer implements Runnable {
private final Buffer<Integer> bf;
private volatile boolean running = true;
private Consumer cons;
public Producer(Buffer<Integer> bf) {
this.bf = bf;
}
public void setConsumer(Consumer cons) {
this.cons = cons;
}
#Override
public void run() {
int counter = 1;
while (running) {
if (bf.isFull()) {
if (cons != null) {
synchronized (cons) {
cons.notify();
}
}
myWait(0);
} else {
bf.add(counter);
counter++;
}
}
}
private void myWait(long millisecs) {
System.out.println("producer is waiting.");
try {
synchronized (this) {
this.wait(millisecs);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("producer is NOT waiting.");
}
public void terminate() {
this.running = false;
}
}
Looks like a regular case of 'missed signal'. Since both consumer and producer just wait without checking a condition, yu have no way to ensure the notify actually happens during the waiting.
e.g. in Consumer :
if (prod != null) {
synchronized (prod) {
prod.notify();
}
}
myWait(0);
Note that if, after prod.notify() the Production thread does all of its work, and notifies the consumer, before it even starts waiting, the consumer will start waiting for a signal that's already been given, and missed.
Always take into account that waiting may not be needed anymore. So always check a condition before even starting to wait. In your case here, the consumer should not even begin waiting if the buffer is full. And likewise the producer should not start waiting if the buffer is empty.
It's also possible to get spurious wake ups. So you'll have to re-check the condition when returning from waiting. The typical idiom is this :
synchronized(monitor) {
while (!stateBasedCondition) {
monitor.wait();
}
}
Edit:
I have a producer class that send some data to the SharedBuffer class. This data is added to an ArrayList with the limit set to 100. There is no problem with adding data to said list, but the consumer class does not manage to get any of the data out of the list.
No output is produced at all (no null or errors).
Edit 2: The method for putting data inside the array was added.
SharedBuffer class:
static final int RESOURCE_LIMIT = 100;
private List<String> data = new ArrayList<String>();
// private boolean done = false;
public boolean isFull(){
return data.size() >= RESOURCE_LIMIT;
}
public boolean isEmpty(){
return data.size() <= 0;
}
public synchronized void putData(String s){
while(this.isFull()){
try{
wait();
}catch(InterruptedException e){
//
e.printStackTrace();
}
}
data.add(s);
//size works and there is data in list.
//System.out.println(data.size() + data.get(0));
public boolean isEmpty(){
return data.size() <= 0;
}
public synchronized String getData(){
while(this.isEmpty()){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
String s_data = (String)(data.get(0));
if(s_data != null){
data.remove(s_data);
System.out.println(s_data);
}
return s_data;
}
Consumer class:
#Override
public void run() {
while(true){
String line = buffer.getData();
if(line != null){
System.out.println(line);
//do stuff with the data.
}
}
}
Change your code (add notyfyAll() invokation)
public synchronized void putData(String s){
while(this.isFull()){
try{
wait();
}catch(InterruptedException e){
//
e.printStackTrace();
}
}
data.add(s);
notifyAll();
}
public synchronized String getData(){
while(this.isEmpty()){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
String s_data = (String)(data.get(0));
if(s_data != null){
data.remove(s_data);
System.out.println(s_data);
}
notifyAll();
return s_data;
}
Also you should synchronize isEmpty and isFull methods because the access to data.
How could I move most of the code into one function or otherwise consolidate it? I'm not so happy with so much duplicate code. Event IntelliJ complains about it...
public boolean closeTrade(Trade trade) {
for (int i=0; i< NUM_CHECKS; i++) {
if (closeBrokerTrade(trade)) return true; // quit loop if successfully closed
//region sleep between checks
if (i < NUM_CHECKS -1) try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
throw propagate(e);
}
//endregion
}
return false;
}
public boolean closeTrade(String ticket) {
for (int i=0; i< NUM_CHECKS; i++) {
if (closeBrokerTrade(ticket)) return true; // quit loop if successfully closed
//region sleep between checks
if (i < NUM_CHECKS -1) try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
throw propagate(e);
}
//endregion
}
return false;
}
protected abstract boolean closeBrokerTrade(Trade trade);
protected abstract boolean closeBrokerTrade(String ticket);
In Java 8 you could pass the correct version of closeBrokerTrade as a lambda:
Declare the function like this:
public boolean closeTrade( BooleanSupplier f) {
// ...
if (f.getAsBoolean()) return true; // quit loop if successfully closed
// ...
return false;
}
And call it like that:
c.closeTrade( () -> c.closeBrokerTrade(new Trade()) );
c.closeTrade( () -> c.closeBrokerTrade("123") );
I need to see the implementation of closeBrokerTrade to be sure about the behaviour, but I would do something like this:
public boolean closeTrade(Trade trade) {
String ticket = ...// generate ticket from trade in whatever way you do it, e.g. trade.getTicket() or trade.toString(), etc. etc.
return closeTrade(ticket);
}
public boolean closeTrade(String ticket) {
for (int i=0; i< NUM_CHECKS*3; i++) {
if (closeBrokerTrade(ticket)) return true; // quit loop if successfully closed
//region sleep between checks
if (i < NUM_CHECKS -1) try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
throw propagate(e);
}
//endregion
}
return false;
}
Correct me if I am wrong or if it is the case that you obtain the trade from the ticket.
If that's not possible, here is my suggestion:
Use generics to represent parameterized trade closing classes like this:
public abstract class ClosingTradeStrategy<T> {
public boolean closeTrade(T trade) {
for (int i=0; i< NUM_CHECKS*3; i++) {
if (closeBrokerTrade(trade)) return true; // quit loop if successfully closed
//region sleep between checks
if (i < NUM_CHECKS -1) try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
throw propagate(e);
}
//endregion
}
return false;
}
protected abstract boolean closeBrokerTrade(T trade);
}
then you can use this to implement different trade closing strategies like this:
public class StringClosingTradeStrategy extends ClosingTradeStrategy<String> {
#Override
protected boolean closeBrokerTrade(String trade) {
... // implement
}
}
public class TradeClosingTradeStrategy extends ClosingTradeStrategy<Trade> {
#Override
protected boolean closeBrokerTrade(Trade trade) {
... // implement
}
}
The advantage of the second approach is that it is easily extensible to other closing strategies.
Use interfaces, as you would if you were to use a Comparator<T>:
private static interface CloseBrokerTradeChecker <T> {
boolean closeBrokerTrade(T t);
}
private static class CloseBrokerTradeCheckerTrade
implements CloseBrokerTradeChecker<Trade> {
#Override
boolean closeBrokerTrade(Trade trade) { ... }
}
private static class CloseBrokerTradeCheckerTicket
implements CloseBrokerTradeChecker<String> {
#Override
boolean closeBrokerTrade(String ticket) { ... }
}
private <T> boolean closeTrade(T t, CloseBrokerTradeChecker<T> checker) {
for (int i=0; i< NUM_CHECKS*3; i++) {
if (checker.closeBrokerTrade(t)) return true; // quit loop if successfully closed
//region sleep between checks
if (i < NUM_CHECKS -1) try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
throw propagate(e);
}
//endregion
}
return false;
}
public boolean closeTrade(Trade trade) {
// TODO: extract CloseBrokerTradeCheckerTrade as a static final variable
return closeTrade(trade, new CloseBrokerTradeCheckerTrade());
}
public boolean closeTrade(String ticket) {
return closeTrade(ticket, new CloseBrokerTradeCheckerTicket());
}
I have a thread which does an action only when it gets exclusive access to 2 semaphores.
public void run(){
boolean a1=false;
boolean a2=false;
boolean a3=false;
while(true){
try{
if(res[1].tryAcquire()==true){
a1=true;
if((res[2].tryAcquire()==true){
a2=true;
if(res[3].tryAcquire()==true)){
a3=true;
System.out.println("Rolled the tobacco");
}
}
}
}
finally{
if(a1){
a1=false;
res[1].release();
}
if(a2){
a2=false;
res[2].release();
}
if(a3){
a3=false;
res[3].release();
}
}
}
}
}
Is there a better way to write this to make sure we do not upset the semaphore acquired count?
Is there a way to check if a semaphore is acquired by the current thread?
In Java 7 a try with Closeable is possible. There certainly must be nicer solutions.
public class Region implements Closeable {
private final Semaphore semaphore;
public Region(Semaphore semaphore) {
this.semaphore = semaphore;
if (!semaphore.tryAcquire()) {
throw NotAcquiredException(semaphore);
}
}
#Override
public void close() {
semaphore.release();
}
}
public class NotAcquiredException extends Exception { ... }
Usage:
public void run() {
boolean a1 = false;
boolean a2 = false;
boolean a3 = false;
while (true) {
try (Closeable r1 = new Region(res[1])) {
a1 = true;
try (Closeable r2 = new Region(res[2])) {
a2 = true;
try (Closeable r3 = new Region(res[3])) {
a3 = true;
System.out.println("Rolled the tobacco");
} catch (IOException e) {
}
} catch (IOException e) {
}
} catch (IOException e) {
}
}
You could separate each acquire into a try...finally, not shorter, but gets rid of some variables and makes it fairly obvious what should happen for each lock. (I changed the array to zero based)
public void run(){
while(true){
if(res[0].tryAcquire()){
try {
if(res[1].tryAcquire()) {
try {
if(res[2].tryAcquire()){
try {
System.out.println("Rolled the tobacco");
} finally {
res[3].release();
}
}
} finally {
res[2].release();
}
}
} finally{
res[1].release();
}
}
}
}
If you need to acquire a lot of locks or do this in several places, then maybe a helper class would be nice. At least hides the boilerplate code of acquire and releasing the semaphores.
public void run() {
SemaphoreHelper semaphoreHelper = new SemaphoreHelper(res);
while (true) {
try {
if (semaphoreHelper.aquireAll()) {
System.out.println("Rolled the tobacco");
}
} finally {
semaphoreHelper.releaseAquired();
}
}
}
private static class SemaphoreHelper {
private final Semaphore[] semaphores;
private int semaphoreIndex;
public SemaphoreHelper(Semaphore[] semaphores) {
this.semaphores = semaphores;
}
public void releaseAquired() {
while (semaphoreIndex > 0) {
semaphoreIndex--;
semaphores[semaphoreIndex].release();
}
}
public boolean aquireAll() {
while (semaphoreIndex < semaphores.length) {
if (!semaphores[semaphoreIndex].tryAcquire()) {
return false;
}
semaphoreIndex++;
}
return true;
}
}