Java并发:试图识别我的乘客来自哪个航班
Java Concurrent: trying to identify my passengers are from which flight
我想在我的项目中找出乘客下船和上船的方法。问题是乘客人数不会按顺序排列,我无法弄清楚哪些航班正在进行这些下机和登机操作。
Objective:想办法给乘客加航班号
package airport_ccp;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class airport_CCP {
public static void main(String[] args) {
Random rand = new Random();
Passengers passsenger = new Passengers();
//runway only got one, two gates
//runway is exclusive event, remain inclusive event for gates only
//gates available: 2, so create blockingqueue<runway>(2)
BlockingQueue<Gate> gates = new ArrayBlockingQueue<Gate>(2);
//threadpool for aircraft, two gates available
//so create a fixed threadpool for gates with 2 maximum
ExecutorService threadpool = Executors.newFixedThreadPool(2);
// 2 active inbound for 2 gates.
for (int i = 1; i <= 2; i++) {
gates.add(new Gate(i));
}
//10 flights
for(int i = 1; i <= 10; i++) {
try {
// 3 secnonds hold for new aircraft
Thread.sleep(rand.nextInt(3000));
threadpool.submit(new Aircraft(i, "land", gates));
//initial thought of input
ExecutorService executor = Executors.newCachedThreadPool();
for(int j=0; j<50; j++){
executor.submit(new Runnable() {
public void run() {
Passengers.getInstance().run();
}
});
}
executor.shutdown();
//input ends
} catch (InterruptedException e) {
e.printStackTrace();
}
}
threadpool.shutdown();
try {
if (threadpool.awaitTermination(100, TimeUnit.SECONDS)) {
for (int i = 1; i <= 2; i++) {
gates.take().printReport();
}
}
} catch (InterruptedException e) {
}
}
}
下面是我的乘客class
package airport_ccp;
import java.util.Random;
import java.util.concurrent.Semaphore;
public class Passengers {
private static Passengers instance = new Passengers();
private Semaphore sema = new Semaphore(50, true); //set max to 50
private int passengercount = 0;
private Passengers() {
}
public static Passengers getInstance(){
return instance;
}
public void run() {
try {
sema.acquire();
System.out.println( "MH " /*ID input*/ + " : Passengers " + passengercount + " Disembarking");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
try {
dorun();
}
finally {
System.out.println( "MH " /*ID input*/ + " : Passengers " + passengercount + " Embarking");
sema.release();
}
}
public void dorun() {
synchronized (this) {
passengercount++;
}
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
synchronized (this) {
passengercount--;
}
}
}
飞机class如果有任何问题
package airport_ccp;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
public class Aircraft implements Runnable{
String status;
int ID;
Date arrival;
BlockingQueue<Gate> gatescount = null;
Gate gate;
public Aircraft(int ID, String status, BlockingQueue<Gate> gatescount) {
this.ID = ID;
this.gatescount = gatescount;
System.out.println("\t Time : " + java.time.LocalDateTime.now() + "\t" + " MH " + ID + " is calling for landing.");
}
@Override
public void run() {
try {
this.status = "land";
gate = gatescount.take();
System.out.println("\t MH " + ID + " has been assigned to " + gate.getName() + ".");
System.out.println( "\t Time : " + java.time.LocalDateTime.now() + "\t" + " MH " + ID + " is " + status + ".");
//Thread.sleep(1000*(1+new Random().nextInt(10)));
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
gate.inc(status);
this.status="depart";
System.out.println("\t Time : " + java.time.LocalDateTime.now() + "\t" + "MH " + ID + " has " + status);
gatescount.add(gate);
}
错误 - 为什么不将航班号传入 run
方法?
// in Passengers
public void run(int id) {
try {
sema.acquire();
System.out.println( "MH " + id + " : Passengers " + passengercount + " Disembarking");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
try {
dorun();
}
finally {
System.out.println( "MH " + id + " : Passengers " + passengercount + " Embarking");
sema.release();
}
}
// when calling Passengers: pass in that ID
for(int i = 1; i <= 10; i++) {
try {
/* ... */
for(int j=0; j<50; j++){
int id = i; // <-- copy to a constant value; once assigned, id is never changed
executor.submit(new Runnable() {
public void run() {
Passengers.getInstance().run(id);
}
});
}
/* ... */
注意,之前的版本使用这段代码,会产生错误,因为i
的值在每次迭代中都会发生变化,而Java需要保证保持不变;使用不变的引用(如上)解决了问题:
for(int j=0; j<50; j++){
executor.submit(new Runnable() {
public void run() {
Passengers.getInstance().run(i); // <-- fails, because i is not, and cannot be made, final
}
});
}
我想在我的项目中找出乘客下船和上船的方法。问题是乘客人数不会按顺序排列,我无法弄清楚哪些航班正在进行这些下机和登机操作。 Objective:想办法给乘客加航班号
package airport_ccp;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class airport_CCP {
public static void main(String[] args) {
Random rand = new Random();
Passengers passsenger = new Passengers();
//runway only got one, two gates
//runway is exclusive event, remain inclusive event for gates only
//gates available: 2, so create blockingqueue<runway>(2)
BlockingQueue<Gate> gates = new ArrayBlockingQueue<Gate>(2);
//threadpool for aircraft, two gates available
//so create a fixed threadpool for gates with 2 maximum
ExecutorService threadpool = Executors.newFixedThreadPool(2);
// 2 active inbound for 2 gates.
for (int i = 1; i <= 2; i++) {
gates.add(new Gate(i));
}
//10 flights
for(int i = 1; i <= 10; i++) {
try {
// 3 secnonds hold for new aircraft
Thread.sleep(rand.nextInt(3000));
threadpool.submit(new Aircraft(i, "land", gates));
//initial thought of input
ExecutorService executor = Executors.newCachedThreadPool();
for(int j=0; j<50; j++){
executor.submit(new Runnable() {
public void run() {
Passengers.getInstance().run();
}
});
}
executor.shutdown();
//input ends
} catch (InterruptedException e) {
e.printStackTrace();
}
}
threadpool.shutdown();
try {
if (threadpool.awaitTermination(100, TimeUnit.SECONDS)) {
for (int i = 1; i <= 2; i++) {
gates.take().printReport();
}
}
} catch (InterruptedException e) {
}
}
}
下面是我的乘客class
package airport_ccp;
import java.util.Random;
import java.util.concurrent.Semaphore;
public class Passengers {
private static Passengers instance = new Passengers();
private Semaphore sema = new Semaphore(50, true); //set max to 50
private int passengercount = 0;
private Passengers() {
}
public static Passengers getInstance(){
return instance;
}
public void run() {
try {
sema.acquire();
System.out.println( "MH " /*ID input*/ + " : Passengers " + passengercount + " Disembarking");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
try {
dorun();
}
finally {
System.out.println( "MH " /*ID input*/ + " : Passengers " + passengercount + " Embarking");
sema.release();
}
}
public void dorun() {
synchronized (this) {
passengercount++;
}
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
synchronized (this) {
passengercount--;
}
}
}
飞机class如果有任何问题
package airport_ccp;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
public class Aircraft implements Runnable{
String status;
int ID;
Date arrival;
BlockingQueue<Gate> gatescount = null;
Gate gate;
public Aircraft(int ID, String status, BlockingQueue<Gate> gatescount) {
this.ID = ID;
this.gatescount = gatescount;
System.out.println("\t Time : " + java.time.LocalDateTime.now() + "\t" + " MH " + ID + " is calling for landing.");
}
@Override
public void run() {
try {
this.status = "land";
gate = gatescount.take();
System.out.println("\t MH " + ID + " has been assigned to " + gate.getName() + ".");
System.out.println( "\t Time : " + java.time.LocalDateTime.now() + "\t" + " MH " + ID + " is " + status + ".");
//Thread.sleep(1000*(1+new Random().nextInt(10)));
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
gate.inc(status);
this.status="depart";
System.out.println("\t Time : " + java.time.LocalDateTime.now() + "\t" + "MH " + ID + " has " + status);
gatescount.add(gate);
}
错误 - 为什么不将航班号传入 run
方法?
// in Passengers
public void run(int id) {
try {
sema.acquire();
System.out.println( "MH " + id + " : Passengers " + passengercount + " Disembarking");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
try {
dorun();
}
finally {
System.out.println( "MH " + id + " : Passengers " + passengercount + " Embarking");
sema.release();
}
}
// when calling Passengers: pass in that ID
for(int i = 1; i <= 10; i++) {
try {
/* ... */
for(int j=0; j<50; j++){
int id = i; // <-- copy to a constant value; once assigned, id is never changed
executor.submit(new Runnable() {
public void run() {
Passengers.getInstance().run(id);
}
});
}
/* ... */
注意,之前的版本使用这段代码,会产生错误,因为i
的值在每次迭代中都会发生变化,而Java需要保证保持不变;使用不变的引用(如上)解决了问题:
for(int j=0; j<50; j++){
executor.submit(new Runnable() {
public void run() {
Passengers.getInstance().run(i); // <-- fails, because i is not, and cannot be made, final
}
});
}