当前位置: 首页 > 知识库问答 >
问题:

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

施同
2023-03-14

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

这是我的主要课程:

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

景信瑞
2023-03-14

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

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

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

锺离霖
2023-03-14

更大的问题是,在while(true)的每次迭代中,您都会创建7个单独的线程。您基本上在这里创建了无限数量的线程和银行帐户。

每次您实例化一个新的DepositThread不单单是创建一个新的事务对象,每个对象都有自己的私有Lock,有效地不同步任何内容。

public class WithdrawThread implements Runnable {

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

    ...
}

您的任何线程之间都没有受到适当保护的共享状态。每个取款线程/DepositThread只尝试通过事务对象获取自己的私有锁。Lock只能在所有线程都可以访问的情况下对资源强制互斥。

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

 类似资料:
  • 问题内容: 我正在以下Java版本上运行单线程Java应用程序: 启用该选项。仍然在启动应用程序时,使用监视系统时看到多个线程正在启​​动。我想尽可能减少启动的进程数,因为我有一个用例,其中涉及运行该应用程序的多个实例,这将达到我正在运行的系统上允许的最大进程数的顶峰。上。除了可以用来减少启动线程数之外,是否还有其他jvm选项? 问题答案: 除了禁用并行或并发GC外,还有以下选项可减少JVM线程数

  • 问题内容: 我有一个正在运行的线程,但是从外面我无法绕过一个值来停止该线程。如何在内部发送false / true值或调用运行线程的公共方法?当我按下按钮1?例如: 或 跟进(校对): 问题答案: 如果您通过类而不是通过a定义它,则可以调用实例方法。 还要注意,由于多个内核具有自己的关联内存,因此您需要警告处理器该状态可能在另一个处理器上更改,并且它需要监视该更改。听起来很复杂,但只需将’vola

  • 问题内容: 我目前正在开发一个涉及在Rails服务器上同步联系人的应用程序。我正在使用Redis服务器和sidekiq在后台执行联系人同步。我的数据库是mongodb,我正在使用Mongoid gem作为ORM。工作流程如下: 电话上的联系人通过应用程序传递到Rails服务器,然后在Rails服务器上,它在Redis服务器中排队。 现在,cron作业会触发连接到Redis的sidekiq并完成作业

  • 在Spark中有几个优化可以减少批处理的时间。这些可以在优化指南中作了讨论。这节重点讨论几个重要的。 数据接收的并行水平 通过网络(如kafka,flume,socket等)接收数据需要这些数据反序列化并被保存到Spark中。如果数据接收成为系统的瓶颈,就要考虑并行地接收数据。注意,每个输入DStream创建一个receiver(运行在worker机器上) 接收单个数据流。创建多个输入DStrea

  • 我运行jmeter脚本将近一周,今天观察到一件有趣的事情。以下是场景: 概述:我正在逐渐增加应用程序的负载。在上一次测试中,我给应用程序加载了100个用户,今天我将加载增加到150个用户。 150名用户测试结果: > 与上次测试相比,请求的响应时间减少了。(这是个好兆头) 吞吐量急剧下降到上一次测试的一半,负载更少。 我的问题是: > 当我的许多请求失败时,我得到了好的响应时间吗? 注:直到100

  • 给出这个简化的示例代码: 如何实现reduce操作的结果也是空的?