Johnathan Yaesu
Johnathan Yaesu

Reputation: 67

How to reduce the amount of time a thread runs?

I am working on a project and i have two threads that run together. The project is a mock bank, and essentially, we have a deposit thread and a withdraw thread. I am having an issue with the deposit threads running to often, and causing the balance of the bank account to rise. (I wish i had this issue in real iife.) How can i reduce the time a thread runs?

Here is my main class:

package bankexample;
import bankexample.depositThread;

public class BankExample {

        public static int balance =0 ;



    public static void main(String[] args) {
        System.out.println("Deposit Thread            Withdrawl Thread           Balance \n");
        System.out.println("--------------            -----------------          --------");
        while (true){
        Thread d1 = new Thread(new depositThread(1));
        Thread d2 = new Thread(new depositThread(2));
        Thread d3 = new Thread(new depositThread(3));
        Thread w1 = new Thread(new WithdrawThread(1));
        Thread w2 = new Thread(new WithdrawThread(2));
        Thread w3 = new Thread(new WithdrawThread(3));
        Thread w4 = new Thread(new WithdrawThread(4));

        d1.start();
        d2.start();
        d3.start();
        w1.start();
        w2.start();
        w3.start();
        w4.start();
        }


    }


}

Here are the withdraw and deposit thread classes:

package bankexample;

/**
 *
 * @author KJ4CC
 */
public class WithdrawThread implements Runnable {
   transaction withdraw = new transaction();
    int threadNum;
    public WithdrawThread(int num){
        threadNum = num;
    }

    public void run(){
        withdraw.withdraw(threadNum);
    }
}

---------------------------
package bankexample;
import bankexample.transaction;

/**
 *
 * @author KJ4CC
 */
public class depositThread implements Runnable  {
   transaction startThread = new transaction();
   public static int balance;
    int threadNum;
    public depositThread(int num){
        threadNum = num;

    }
    @Override
    public void run(){


       try {
                Thread.sleep(100);
                startThread.deposit(threadNum);

        } catch (Exception e) {


        }



    }
}

and finally her is the transaction class:

package bankexample;
import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.Condition;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 *
 * @author KJ4CC
 */
public class transaction extends BankExample   {

    private Lock accessLock = new ReentrantLock();
    private Condition cond = accessLock.newCondition();
    private boolean occupied = false;
    Random rand = new Random();

    public void deposit(int threadNum) throws InterruptedException{
        //random amount for amount to deposit into bank mod 200
        int amount = rand.nextInt(200);

        //locks the thread 
        //System.out.println("Balance before Deposit  " + balance);
        accessLock.lock();
        try {
            //System.out.println(getBalance.getbalance());
            //adds the amount to the balance.
           if (occupied == false){
            occupied = true;
            balance = (balance + amount);
            //outputs to terminal 
            System.out.println("Thread " + threadNum + " Deposits " + amount + "\t\t\t\t Balance is " + balance);
            occupied = false;
            Thread.sleep(10000);
            //signals any awiting widthdraw threads 
            cond.signal();

           }
        } finally {
            //unlocks thread 

            accessLock.unlock();
        }

    }
    public void withdraw(int threadNum){
        //getting a random amount mod50
        int amount = rand.nextInt(50);

        //locking the thread 
        accessLock.lock();
        try {
            //test print out 


           //checks to see if the amount is less than the balance 
            if (amount < balance && occupied == false) {
                occupied = true;
               // System.out.println("Balance before withdraw " + balance);
                balance = (balance - amount );

                System.out.println("\t\t\tThread " + threadNum + " withdrawls " + amount + "\t Balance is " + balance);
                cond.signalAll();
                occupied = false;
                //if it isnt we can not make a withdraw so we have to wait for a deposit 
            } else {

                System.out.println("\t\t\tThread " + threadNum + " Failed to withdrawl " + amount + "\t Balance is " + balance);
                cond.await();

            }
            //unlock the thread 
        } catch (InterruptedException ex) {
            Logger.getLogger(transaction.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            accessLock.unlock();
        }
    }
}

I have tried to have the threads sleep before they hit the lock condition, but unfortunately, it doesn't work.

Here is a sample from the output:
Deposit Thread            Withdrawl Thread           Balance 

--------------            -----------------          --------
            Thread 1 Failed to withdrawl 4   Balance is 0
            Thread 2 Failed to withdrawl 49  Balance is 0
            Thread 3 Failed to withdrawl 21  Balance is 0
            Thread 4 Failed to withdrawl 13  Balance is 0
            Thread 1 Failed to withdrawl 30  Balance is 0
            Thread 2 Failed to withdrawl 15  Balance is 0
            Thread 3 Failed to withdrawl 18  Balance is 0
            Thread 4 Failed to withdrawl 25  Balance is 0
            Thread 2 Failed to withdrawl 27  Balance is 0
            Thread 1 Failed to withdrawl 9   Balance is 0
            Thread 3 Failed to withdrawl 0   Balance is 0
            Thread 4 Failed to withdrawl 21  Balance is 0
            Thread 1 Failed to withdrawl 31  Balance is 0
            Thread 2 Failed to withdrawl 32  Balance is 0
            Thread 3 Failed to withdrawl 47  Balance is 0
            Thread 4 Failed to withdrawl 8   Balance is 0
            Thread 1 Failed to withdrawl 22  Balance is 0
            Thread 2 Failed to withdrawl 38  Balance is 0
            Thread 3 Failed to withdrawl 43  Balance is 0
            Thread 4 Failed to withdrawl 2   Balance is 0
            Thread 1 Failed to withdrawl 19  Balance is 0
            Thread 2 Failed to withdrawl 39  Balance is 0
            Thread 3 Failed to withdrawl 43  Balance is 0
            Thread 4 Failed to withdrawl 48  Balance is 0
            Thread 1 Failed to withdrawl 45  Balance is 0
            Thread 3 Failed to withdrawl 45  Balance is 0
            Thread 2 Failed to withdrawl 25  Balance is 0
            Thread 4 Failed to withdrawl 21  Balance is 0
Thread 2 Deposits 188                Balance is 188
Thread 3 Deposits 128                Balance is 316
Thread 2 Deposits 54                 Balance is 370
Thread 1 Deposits 123                Balance is 493
Thread 3 Deposits 59                 Balance is 552
            Thread 1 withdrawls 38   Balance is 514
            Thread 2 withdrawls 35   Balance is 479
            Thread 3 withdrawls 40   Balance is 439
            Thread 4 withdrawls 5    Balance is 434
Thread 1 Deposits 179                Balance is 613
Thread 1 Deposits 108                Balance is 1027
Thread 2 Deposits 56                 Balance is 919
Thread 1 Deposits 96                 Balance is 863
Thread 2 Deposits 101                Balance is 767
Thread 3 Deposits 149                Balance is 1176
Thread 3 Deposits 53                 Balance is 666
Thread 2 Deposits 67                 Balance is 1277
Thread 1 Deposits 108                Balance is 1385
Thread 3 Deposits 34                 Balance is 1277
Thread 2 Deposits 69                 Balance is 1466
Thread 3 Deposits 49                 Balance is 1561
            Thread 4 withdrawls 32   Balance is 1529
Thread 1 Deposits 12                 Balance is 1561
Thread 2 Deposits 46                 Balance is 1561
Thread 1 Deposits 99                 Balance is 15

Upvotes: 0

Views: 317

Answers (2)

su45
su45

Reputation: 313

The bigger issue is that on each iteration of the while(true), you are creating 7 separate Threads. You are basically spawning an infinite number of Threads and bank accounts here.

Each time you instantiate a new DepositThread or WithdrawThread, you are creating a new transaction object, each with its own private Lock that effectively synchronizes nothing.

public class WithdrawThread implements Runnable {

    //creates a new Lock per *Thread*
    transaction withdraw = new transaction(); 

    ...
}

There is no properly-protected shared state among any of your threads. Each WithdrawThread/DepositThread is only ever attempting to acquire its own private Lock via the transaction object. A Lock can only enforce mutual exclusion on a resource if all Threads can access it.

A better solution would be to have one Transaction object, whose reference is passed as a parameter to each Thread.

Upvotes: 2

Warren Dew
Warren Dew

Reputation: 8928

It sounds like you intend to have two threads that run at the same time, one deposit thread and one withdrawal thread, but that's not what you have. Rather, your main loop is creating three separate deposit threads and four separate withdrawal threads each time through the loop, and the loop seems to run indefinitely, so you're creating an unlimited number of threads. Since the deposit threads have a 100ms delay and the withdrawal threads don't, a bunch of the withdrawal threads run, then after 100ms a bunch of deposit threads run. In addition, the threads are not actually accessing a common "bank account" balance.

To start with, have the main thread create just one withdrawal thread and one deposit thread, and then exit. Then put the loops in the deposit and withdrawal threads. That will fix some of your problems.

After you've done that, you'll probably still have other problems, but they'll be different problems and you may be able to figure them out and fix them by yourself. If not, you can always post a new question on them.

Upvotes: 1

Related Questions