有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我正在做一个项目,我有两个线程一起运行。该项目是一个模拟银行,本质上,我们有一个存款线程和一个取款线程。我有一个问题,存款线程运行频繁,并导致银行账户余额上升。(我希望我在现实生活中有这个问题。)如何减少线程运行的时间

这是我的主要课程:

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) 个答案

  1. # 1 楼答案

    听起来你想让两个线程同时运行,一个存款线程和一个取款线程,但这不是你想要的。相反,您的主循环每次通过循环创建三个单独的存款线程和四个单独的取款线程,并且循环似乎无限期地运行,因此您创建的线程数量是无限的。由于存款线程有100毫秒的延迟,而取款线程没有,所以会运行一组取款线程,然后在100毫秒后运行一组存款线程。此外,这些线程实际上并没有访问公共的“银行账户”余额

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

    这样做之后,你可能仍然会有其他问题,但它们是不同的问题,你可以自己解决它们。如果没有,你可以随时在上面发布一个新问题

  2. # 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对象,将其引用作为参数传递给每个线程