2017-04-07 515 views
0

你能幫我解決這個問題。多線程的Java如何讓線程等待一段時間

停車問題
「有N停車地段在一個停車場,只能有一輛車如果所有的停車場都被佔用,那麼汽車會等待一段時間,如果仍然沒有免費的停車場,它就會離開。「

它需要使用線程來解決(由will同步)。

這裏是我的代碼:
停車

class Parking implements Runnable { 
private Thread thread; 
private String threadName; 
static int parkingLots; 

static { 
    parkingLots = 5; 
} 

Parking(String threadName) { 
    this.threadName = threadName; 
} 

public void run() { 
    if (parkingLots > 0) { 
     long restTime = (long) (Math.random() * 2000); 
     try { 
      parkingLots--; 
      System.out.println("Car " + threadName + " stands in the parking lot"); 
      Thread.sleep(restTime); 
     } catch (InterruptedException e) { 
     } 
     parkingLots++; 
     System.out.println("Car " + threadName + " has left parking, it stood there" + ((double)restTime/(double)1000) + " s"); 
    } else 
     System.out.println("Car " + threadName + " has left parking"); 
} 

public void start() { 
    if (thread == null) { 
     thread = new Thread(this, threadName); 
     thread.start(); 
    } 
} 
} 

主要

public class Main { 
    public static void main(String[] args) { 
     ArrayList<Parking> parking = new ArrayList<Parking>(); 

     for (int i = 0; i < 15; i++) { 
      parking.add(new Parking(String.valueOf(i + 1))); 
     } 
     for (Parking i: parking) { 
      i.start(); 
     } 
    } 
} 

我希望看到的(當有2個停車場和4輛汽車):

Car 1 stands in the parking lot 
Car 2 stands in the parking lot 
Car 3 is waiting 
Car 4 is waiting 
Car 3 has left parking 
Car 2 has left parking, it stood there 1.08 s 
Car 4 stands in the parking lot 
Car 1 has left parking, it stood there 1.71 s 
Car 4 has left parking, it stood there 0.83 s 

但是我得到了(當有2個停車場和4輛車時):所有第一輛車(1和2)站在停車位,其他車輛(3和4)剛剛離開,因爲沒有免費停車場。即使有15輛車,他們仍然無法進入。

那麼我該如何讓汽車在離開前等一段時間呢?如果有免費的停車場,那麼他們會去的,否則他們會離開停車場。

任何幫助,將不勝感激!謝謝!

+1

,這個代碼需要一些嚴重的重構是以正確的方式完成 –

+1

不要在'Runnable'中放置'Thread'。它應該是相反的。把主要班級想象成一個協調員;它將管理'ParkingLot'和'Car'類型的線程和實例的細節,每個類型都有一個'Runnable#run'方法。 –

回答

1

修改你的代碼,看看是否有效。

public class Parking implements Runnable { 
    private Thread thread; 
    private String threadName; 
    static int parkingLots; 

    static { 
     parkingLots = 5; 
    } 

    Parking(String threadName) { 
     this.threadName = threadName; 
    } 

    public void run() { 
     long restTime = (long) (Math.random() * 2000); 
     if (parkingLots > 0) { 
      checkparking(); 
     } else { 
      try { 
       System.out.println("Car " + threadName + " is waiting"); 
       Thread.sleep(restTime); 
       System.out.println("Car " + threadName + " is checking for free parkinglot"); 
       checkparking(); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

    } 

    public void checkparking() { 
     if (parkingLots > 0) { 
     long restTime = (long) (Math.random() * 2000); 
     try { 
      parkingLots--; 
      System.out.println("Car " + threadName + " stands in the parking lot"); 
      Thread.sleep(restTime); 
     } catch (InterruptedException e) { 
     } 
     parkingLots++; 
     System.out.println(
       "Car " + threadName + " has left parking, it stood there" + ((double) restTime/(double) 1000) + " s"); 

    } else { 
     System.out.println(
       "Car " + threadName + " has left since there is no parking space"); 
    } 
    } 

    public void start() { 
     if (thread == null) { 
      thread = new Thread(this, threadName); 
      thread.start(); 
     } 
    } 

} 

公共類主要{

 public static void main(String[] args) { 
      ArrayList<Parking> parking = new ArrayList<Parking>(); 

      for (int i = 0; i < 15; i++) { 
       parking.add(new Parking(String.valueOf(i + 1))); 
      } 
      for (Parking i: parking) { 
       i.start(); 
      } 
     } 
} 

輸出:

Car 2 stands in the parking lot 
Car 1 stands in the parking lot 
Car 7 is waiting 
Car 5 stands in the parking lot 
Car 3 stands in the parking lot 
Car 6 is waiting 
Car 4 stands in the parking lot 
Car 9 is waiting 
Car 8 is waiting 
Car 10 is waiting 
Car 11 is waiting 
Car 12 is waiting 
Car 13 is waiting 
Car 14 is waiting 
Car 15 is waiting 
Car 4 has left parking, it stood there0.049 s 
Car 14 is checking for free parkinglot 
Car 14 stands in the parking lot 
Car 5 has left parking, it stood there0.366 s 
Car 2 has left parking, it stood there0.461 s 
Car 12 is checking for free parkinglot 
Car 12 stands in the parking lot 
Car 15 is checking for free parkinglot 
Car 15 stands in the parking lot 
Car 1 has left parking, it stood there0.882 s 
Car 9 is checking for free parkinglot 
Car 9 stands in the parking lot 
Car 10 is checking for free parkinglot 
Car 10 has left since there is no parking space 
Car 3 has left parking, it stood there1.014 s 
Car 13 is checking for free parkinglot 
Car 13 stands in the parking lot 
Car 15 has left parking, it stood there0.937 s 
Car 6 is checking for free parkinglot 
Car 6 stands in the parking lot 
Car 11 is checking for free parkinglot 
Car 11 has left since there is no parking space 
Car 13 has left parking, it stood there0.344 s 
Car 7 is checking for free parkinglot 
Car 7 stands in the parking lot 
Car 8 is checking for free parkinglot 
Car 8 has left since there is no parking space 
Car 7 has left parking, it stood there0.054 s 
Car 14 has left parking, it stood there1.731 s 
Car 9 has left parking, it stood there1.359 s 
Car 12 has left parking, it stood there1.877 s 
Car 6 has left parking, it stood there1.787 s 
0

您沒有使用和同步,你的類不應該實現Runnable和您所使用的語義是不正確。

例如,在啓動汽車不能停車/離開之後,多線程是關於某些東西被多個線程同時訪問而不會導致不一致的狀態,在您的情況下,您基本上只是創建線程並執行某些操作。

你的結構應該是這樣的:你不使用同步,你應該使用的鎖定對象,而一些條件變量來實現這個正確的方式

import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.locks.Condition; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 

public class Parking { 

    private final Lock monitor = new ReentrantLock(); 
    private final Condition lotAvailable = monitor.newCondition(); 

    private List<Car> parkedCars = new ArrayList<>(); 

    private final int maxCapacity; 
    private int occupied; 

    public Parking(int maxCapacity) { 
     this.maxCapacity = maxCapacity; 
    } 

    private boolean tryPark(Car car, int maxWaitingMillis) throws InterruptedException{ 
     try { 
      monitor.lock(); 
      if(occupied >= maxCapacity){ 
       long nanos = lotAvailable.awaitNanos(maxWaitingMillis); 
       while (occupied >= maxCapacity) { 
        if (nanos <= 0L) 
         return false; 
        nanos = lotAvailable.awaitNanos(nanos); 
       } 
       ++occupied; 
       parkedCars.add(car); 
       return true; 
      } 
      ++occupied; 
      parkedCars.add(car); 
      return true; 
     }catch (InterruptedException ie){ 
      System.out.println(ie.getMessage()); 
      throw ie; 
     }finally { 
      monitor.unlock(); 
     } 

    } 

    private void leave(Car car){ 
     try { 
      monitor.lock(); 
      if(parkedCars.remove(car)) { 
       --occupied; 
       lotAvailable.signal(); 
      } 
     }catch (Exception e){ 
      System.out.println(e.getMessage()); 
     }finally { 
      monitor.unlock(); 
     } 
    } 


}