Consolidating duplicate code in almost identical methods - java

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());
}

Related

Producer-consumer problem - both end up waiting

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();
}
}

java synchronization and starvation

i have made a program and expecting output like this :
A
1
a
B
2
b
C
3
c
...
E
5
e
here is my code i think am getting starvation problem plz help me
class Product {
static boolean flag1, flag2, flag3;
synchronized void printLwrAlpha(char value) {
// System.out.println(flag3+": inside lwr_alpha");
if (!flag3)
try {
wait();
} catch (Exception ex) {
System.out.println(ex);
}
System.out.println(value);
flag3 = false;
flag1 = false;
System.out.println("before notify");
notify();
System.out.println("after notify");
}
synchronized void printUprAlpha(char n) {
// System.out.println(flag1+": inside upr_alpha");
if (flag1)
try {
wait();
} catch (Exception e) {
System.out.println(e);
}
System.out.println(n);
// System.out.println(num);
flag1 = true;
flag2 = true;
notify();
}
synchronized void printNum(int num) {
// System.out.println(flag2+": inside num");
if (!flag2)
try {
wait();
} catch (Exception e) {
System.out.println(e);
}
// System.out.println(n);
System.out.println(num);
flag2 = false;
flag3 = true;
notify();
}
}
class PrintNum implements Runnable {
Product p;
PrintNum(Product p) {
this.p = p;
new Thread(this, "Producer").start();
try {
Thread.sleep(1000);
} catch (Exception ex) {
System.out.println(ex);
}
}
public void run() {
for (int i = 1; i <= 5; i++)
p.printNum(i);
}
}
class PrintLwrAlpha implements Runnable {
Product p;
static char ch = 'a';
PrintLwrAlpha(Product p) {
this.p = p;
new Thread(this, "Producer").start();
try {
Thread.sleep(1000);
} catch (Exception ex) {
System.out.println(ex);
}
}
public void run() {
for (int i = 1; i <= 5; i++) {
char c = (char) (ch + (i - 1));
p.printLwrAlpha(c);
}
}
}
class PrintUprAlpha implements Runnable {
Product p;
static char ch = 'A';
PrintUprAlpha(Product p) {
this.p = p;
new Thread(this, "Producer").start();
try {
Thread.sleep(1000);
} catch (Exception ex) {
System.out.println(ex);
}
}
public void run() {
for (int i = 1; i <= 5; i++) {
char c = (char) (ch + (i - 1));
p.printUprAlpha(c);
}
}
}
public class MainClass1 {
public static void main(String ar[]) {
Product p = new Product();
new PrintNum(p);
new PrintUprAlpha(p);
new PrintLwrAlpha(p);
}
}
i am getting this output:
run:
A
1
B
2
C
3
D
4
E
5
a
before notify
after notify
i think after this program is going in to starvation
Replace all your ifs, e.g.
if (!flag3)
with while loops
while (!flag3)
If I understand correctly your problem is that you're trying to use a single wait object with multiple threads. The common scenario for wait/notify is as follows: the one thread is waiting for resource to become available while the second thread produces the resource and notifies the first thread.
In code it may look like this:
class ResourceFactory {
public synchronized void produce()
{
// make the resource available
obj.notify();
}
public synchronized void consume()
{
if( /* resource is not available */ ) {
obj.wait();
}
// do something with resource
}
}
When multiple threads are trying to wait on a single object the problem is that it's up to implementation which thread would be awaken after notify call. I think you should make 3 different objects and do something like this:
// thread 1
obj1.wait();
obj2.notify()
// thread 2
obj2.wait();
obj3.notify()
// thread 3
obj3.wait();
obj1.notify()
Be careful and try not to deadlock your code.
And at last your code. First two threads are waiting and awaken each other despite the flags. And when the third thread is awaken there's no thread to notify it. So it's a classical deadlock.

java semaphore idiom

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;
}
}

Java - multithreading and synchronization

I have two very similar programs each trying to run two threads OddThread and EvenThread and trying to print the odd and even numbers in sequence . While the first one works , the second one hangs . Can anyone please pinpoint the bug in the second program ?
The first one which works :
public class ThreadTest {
public static void main(String[] args) {
System.out.println("Odd Even test");
NumHolder objNumHolder = new NumHolder();
Odd o1 = new Odd(objNumHolder, "Odd Number Thread");
Even e1 = new Even(objNumHolder, "Even Number Thread");
o1.start();
e1.start();
}
}
class NumHolder {
private int intCurrNum;
private boolean isEven = false;
public synchronized void printOddNumber(String tname) {
while (isEven == true){
try {
wait();
}catch (InterruptedException e) {
}
}
isEven = true;
System.out.println("Thread Name="+tname + "===Number="+intCurrNum);
intCurrNum += 1;
notifyAll();
}
public synchronized void printEvenNumber(String tname) {
while (isEven == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
isEven = false;
System.out.println("Thread Name="+tname + "===Number="+intCurrNum);
intCurrNum += 1;
notifyAll();
}
}
class Even extends Thread {
private NumHolder objNumHolder;
public Even(NumHolder p_objNumHolder, String name) {
super(name);
objNumHolder=p_objNumHolder;
}
public void run() {
for (int i = 0; i < 10; i++) {
objNumHolder.printEvenNumber(getName());
}
}
}
class Odd extends Thread {
private NumHolder objNumHolder;
public Odd(NumHolder p_objNumHolder,String name) {
super(name);
objNumHolder = p_objNumHolder;
}
public void run() {
for (int i = 0; i < 10; i++) {
objNumHolder.printOddNumber(getName());
}
}
}
The second code which hangs :
class PrintClass {
int intCurrNum;
private boolean isEven = false;
synchronized void printOdd(){
while(isEven){
try{
wait();
}catch(InterruptedException ie){
System.out.println("Interrupted exception in printOdd()");
ie.printStackTrace();
}
isEven = true;
System.out.println("Thread Name="+Thread.currentThread().getName() + "===Number="+intCurrNum);
intCurrNum += 1;
notifyAll();
}
}
synchronized void printEven(){
while(!isEven){
try{
wait();
}catch(InterruptedException ie){
System.out.println("Interrupted exception in printEven()");
ie.printStackTrace();
}
isEven = false;
System.out.println("Thread Name="+Thread.currentThread().getName() + "===Number="+intCurrNum);
intCurrNum += 1;
notifyAll();
}
}
}
class ThreadOdd extends Thread {
PrintClass pc = null;
ThreadOdd(PrintClass pc , String name){
super(name);
this.pc = pc;
}
public void run(){
for (int i = 0; i < 10; i++) {
pc.printOdd();
}
}
}
class ThreadEven extends Thread {
PrintClass pc = null;
ThreadEven(PrintClass pc,String name){
super(name);
this.pc = pc;
}
public void run(){
for (int i = 0; i < 10; i++) {
pc.printEven();
}
}
}
public class EvenOddPrintClass {
public static void main(String[] args){
PrintClass pc = new PrintClass();
Thread to = new ThreadOdd(pc,"ThreadOdd");
Thread te = new ThreadEven(pc,"ThreadEven");
to.start();
te.start();
}
}
Thanks.
I suggest you run your code in the debugger and step through both threads. It's very educational. You will see exactly where the error is.
In both versions, isEven starts out as false.
In the first version, printOddNumber will skip the whole while loop, print the odd number, set isEven to true and notify the even thread, which will print the even number and notify the odd thread again etc. in sequence.
In the second version, printOddNumber will skip the whole while loop, including printing the number and notifying the even thread. After 10 attempts it will exit without having printed anything, and leaving the even thread hanging without ever having notified it.
Interesting. So initially the isEven = false. If the printOdd() is called first then the while (isEven) test is false so printOdd() will exit immediately without generating any output. The while loops in your first program only encompass the wait test, not the entire method.
Then when printEven() is called by the other thread, it will call wait() and hang since there is no other thread to call notifyAll().
You only should want the while loop around the wait since you are going to exit after you print out the even or odd number anyway, right? So the logic in the first program is correct.
public class CountDownApp
{
public static void main(String[] args)
{
Thread count1 = new CountDownEven();
Thread count2 = new CountDownOdd();
count1.start();
count2.start();
}
}
class CountDownEven extends Thread
{
public void run()
{
for(int i=10;i>0;i-=2)
{
System.out.print(+i+"-");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class CountDownOdd extends Thread
{
public void run()
{
for(int i=9;i>0;i-=2)
{
System.out.print(+i+"-");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

Threading ArrayIndexOutofBoundException

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.

Categories

Resources