如何减少线程运行的时间?

时间:2016-09-25 19:41:27

标签: java multithreading

我正在研究一个项目,我有两个一起运行的线程。该项目是一个模拟银行,基本上,我们有一个存款线程和一个撤销线程。我遇到存款线程经常运行的问题,导致银行账户余额上升。 (我希望我能真正解决这个问题。)如何减少线程运行的时间?

这是我的主要课程:

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


    }


}

以下是撤销和存款线程类:

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) {


        }



    }
}

最后她是交易类:

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

我试图让线程在锁定状态之前保持睡眠状态,但不幸的是,它并没有起作用。

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

2 个答案:

答案 0 :(得分:2)

更大的问题是,在while(true)每次迭代上,您将创建7个单独的线程。你基本上是在这里产生无限数量的线程和银行账户。

每次实例化新的DepositThreadWithdrawThread时,您都会创建一个新的transaction对象,每个对象都有自己的私有Lock,可以有效地同步任何内容。

public class WithdrawThread implements Runnable {

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

    ...
}

您的任何线程之间都没有受到适当保护的共享状态。每个WithdrawThread / DepositThread只是试图通过transaction对象获取自己的私有锁。如果所有线程都可以访问资源,则Lock只能对资源实施互斥。

更好的解决方案是拥有一个 Transaction对象,其引用作为参数传递给每个线程。

答案 1 :(得分:1)

听起来你打算有两个同时运行的线程,一个存款线程和一个提取线程,但这不是你拥有的。相反,你的主循环每次通过循环创建三个独立的存储线程和四个单独的撤销线程,并且循环似乎无限期地运行,因此你创建了无限数量的线程。由于存款线程有100毫秒的延迟并且提取线程没有,所以一堆提取线程运行,然后在100ms后运行一堆存款线程。此外,线程实际上并没有访问一个共同的银行帐户&#34;平衡。

首先,让主线程只创建一个提取线程和一个存款线程,然后退出。然后将循环放入存款和取款线程中。这将解决你的一些问题。

在您完成此操作后,您可能仍会遇到其他问题,但他们会遇到不同的问题,您可以自行解决问题并进行修复。如果没有,您可以随时发布新问题。