通知后的Java释放锁会导致新线程出现

通知后的Java释放锁会导致新线程出现,java,multithreading,notify,Java,Multithreading,Notify,!![在此输入图像描述][1]有人知道为什么在释放锁后会创建新线程吗? 我有一个线程监听要更改的请求状态(字符串)(正在等待锁定对象),另一个线程正在更改它: @Override public void run() { while(!customerGroupDetails.isEmpty()){ RentalRequest request=customerGroupDetails.remove(); management.addRentalRequest

!![在此输入图像描述][1]有人知道为什么在释放锁后会创建新线程吗? 我有一个线程监听要更改的请求状态(字符串)(正在等待锁定对象),另一个线程正在更改它:

@Override
public void run() {
    while(!customerGroupDetails.isEmpty()){
        RentalRequest request=customerGroupDetails.remove();
        management.addRentalRequest(request);
        getLogger().info(Thread.currentThread().getName() + ": handling new request:" + request.toString());
        getLogger().info(Thread.currentThread().getName() + ": waiting for request status to be FULFILLED");
        request.waitForStatus("FULFILLED");
        ExecutorService ex=Executors.newCachedThreadPool();
        CompletionService<Double> cs= new ExecutorCompletionService<Double>(ex);
        CreateStaySimulationForClient stay=new CreateStaySimulationForClient(cs,request.getDuration());
        request.setRequestStatus("INPROGRESS");
        getLogger().info(Thread.currentThread().getName() + ": Simulating stay and setting requets status to INPROGRESS");
        customerGroupDetails.forEach(stay);
        Future<Double> damage=null;
        Double recivedDamage=new Double(0);
        double sum=0;
        int numberOfCustomers=customerGroupDetails.size();
        for(int i=0;i<numberOfCustomers;i++){
            try {
                damage=cs.take();
                recivedDamage=damage.get();
                getLogger().info(" damage for assetContent is " + recivedDamage);
                sum=sum+recivedDamage;



            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        getLogger().info(Thread.currentThread().getName() + ": Asset is damaged by " + sum);
        request.getAsset().damage(sum);
        if(request.getAsset().getHealth()<65){
            management.changeAssetStatus(request.getAsset(), "UNAVILABLE");
            DamageReport damageReport=new DamageReport(request.getAsset(), sum);
            management.addDamageReport(damageReport);
        }
        else{
            management.changeAssetStatus(request.getAsset(), "AVAILABLE");
            getLogger().info(request.getAsset() + " is now available");
        }

        request.setRequestStatus("COMPLETE");
        getLogger().info(Thread.currentThread().getName() + ": damage report has been submitted to managment - this request status is COMPLETE");

    }
    getLogger().info(Thread.currentThread().getName() + ": no more requests for me - i'm done");

}

@Override
public void run() {
    int totalTime = 0;
    boolean shiftEnded = false;
    getLogger().info(clerkDetails.toString() + ": starting new shift");
    while (!shiftEnded&& !Thread.currentThread().isInterrupted()) {
        RentalRequest req = null;
        getLogger().info(clerkDetails.toString() + ": trying to take request");
        try {
            req = rentalRequests.take();
        } catch (InterruptedException e) {
            if (numberOfRequests.get() == 0) {
                getLogger()
                        .info(clerkDetails.toString()
                                + " was interrupted becuase there are no more requests");
                shiftEnded=true;
            } else {
                getLogger().warning(
                        clerkDetails.toString()
                                + " was interrupted unexpectedly"
                                + e.toString());

            }
        }
        if (req!=null) {
            int num=numberOfRequests.decrementAndGet();
            getLogger().info(clerkDetails.toString() + ": recived request: "+req.toString()+",number of requests left is " +num +", now finding appropreiate asset");
            Asset asset = assets.getAsset(req.getAssetType(),
                    req.getAssetSize());
            assets.changeAssetStatus(asset, "BOOKED");

            getLogger().info(clerkDetails.toString() + ": Asset " + asset.toString() + " is now BOOKED");
            req.setAsset(asset);

            management.updateEarnings(asset.getCostPerNight()
                    * req.getDuration());

            int time = getClerkDetails().getLocation().calculateDistance(
                    asset.getLocation());
            totalTime = totalTime + time;
            getLogger().info(clerkDetails.toString() + ": going to Asset - sleeping:" + time);

            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
                getLogger().warning(
                        clerkDetails.toString()
                                + " was interrupted unexpectedly"
                                + e.toString());



            }

            req.setRequestStatus("FULFILLED");

            getLogger().info(clerkDetails.toString() + ": request status set to: FULFILLED");
            getLogger().info(clerkDetails.toString()  +": time left for this shift is " + (8 -totalTime));

            if (totalTime > 8) {
                shiftEnded = true;


            }
            if (numberOfRequests.get() == 0) {
                shiftEnded=true;
                management.interrupt();

                getLogger().info(clerkDetails.toString() + ": finished last requets for this simulation - tyring to interrupet managment");
            }

        }


    }
    management.countDownClerksBarriar();
    getLogger().info(clerkDetails.toString() + ": finished shift");

}

public void setRequestStatus(String status) {
    synchronized(statusLock){
        //if(!getRequestStatus().equalsIgnoreCase(status)){
            requestStatus = status;
            statusLock.notifyAll();
        //}
    }


}
public void waitForStatus(String status){
    synchronized (statusLock) {
    while(!getRequestStatus().equalsIgnoreCase(status)){

            try {
                statusLock.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}
@覆盖
公开募捐{
而(!customerGroupDetails.isEmpty()){
RentalRequest=customerGroupDetails.remove();
管理。添加请求(请求);
getLogger().info(Thread.currentThread().getName()+”:处理新请求:“+request.toString());
getLogger().info(Thread.currentThread().getName()+“:等待请求状态被满足”);
请求。waitForStatus(“已满足”);
ExecutorService ex=Executors.newCachedThreadPool();
CompletionService cs=新的ExecutionCompletionService(ex);
CreateStaySimulationForClient stay=新建CreateStaySimulationForClient(cs,request.getDuration());
请求。设置请求状态(“INPROGRESS”);
getLogger().info(Thread.currentThread().getName()+“:模拟停留并将请求状态设置为INPROGRESS”);
customerGroupDetails.forEach(住宿);
未来损害=零;
双倍收到的损坏=新的双倍(0);
双和=0;
int numberOfCustomers=customerGroupDetails.size();

对于(int i=0;i此行:
ExecutorService ex=Executors.newCachedThreadPool();
创建线程池。 此行:
CreateStaySimulationForClient stay=new CreateStaySimulationForClient(cs,request.getDuration());
大概是使用线程池创建了一些东西

您在截图中提到的线程是该池中的线程之一。它确实有一个名称,其中包含“pool”,以便您知道它来自何处:)


另外,请注意,您在循环中执行此操作(线程池创建),这几乎肯定不是您想要执行的操作。

显然-我以前怎么没有想到?谢谢!
"pool-15-thread-2" prio=6 tid=0x000000000c20e000 nid=0x23d8 waiting on condition [0x00000000112be000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000000e0badf08> (a java.util.concurrent.SynchronousQueue$TransferStack)
    at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
    at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(Unknown Source)
    at java.util.concurrent.SynchronousQueue$TransferStack.transfer(Unknown Source)
    at java.util.concurrent.SynchronousQueue.poll(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
    - None