问题描述:1个父线程,并发生成N(N作为参数传入)个子线程。设定全局变量 g_sum=0,每个子进程在 0至200中随机选择一个数;
若子线程的进程ID是奇数则g_sum=g_sum-随机数,
若子线程的进程ID是偶数则g_sum=g_sum+随机数,
每个子线程对g_sum操作完成后都要通知父线程,父线程收到通知后输出“子线程{进程ID}对g_sum进行了[加/减]{随机数}操作,当前g_sum={新值}”,父进程将每次g_sum的新值进行记录,并对已记录的数组进行升序排列,每次重新排列后进行一次输出。
 
想法一  回调方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
   | public class ThreadTest { 	public static int g_sum = 0; 	public static List<Integer> g_sumList = new ArrayList<Integer>(); 	public static Object o= new Object();
  	@SuppressWarnings("unchecked") 	public ThreadTest() { 		super(); 		this.g_sumList.add(g_sum); 	}
  	
 
 
 
 
  	public static void callBack(int id, int num, int flag) { 		String mark = flag == 1 ? "加" : "减"; 		System.out.println("子线程" + id + ":对g_num进行了" + mark + "" + num + "操作,当前g_sum=" + g_sum); 		 		g_sumList.add(g_sum); 		Collections.sort(g_sumList); 		SimpleDateFormat sdf = new SimpleDateFormat();		         sdf.applyPattern("yyyy-MM-dd HH:mm:ss a");			         Date date = new Date();								 		System.out.println(sdf.format(date)+" g_sum历史值升序为:"); 		System.out.println(g_sumList); 		System.out.println(); 	} 	 	 	public  void  generateThreads(int N) { 		int randomNum; 		for (int id = 1; id <= N; id++) { 			randomNum = (int) (Math.random() * 200); 			 			MyRunnable myRunnable = new MyRunnable(id, randomNum); 			Thread t=new Thread(myRunnable); 			t.start(); 		} 		 	}
  	public static void main(String[] args) { 		ThreadTest test = new ThreadTest(); 		test.generateThreads(10); 	} }
  | 
 
MyRunnable.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   | public class MyRunnable implements Runnable { 	private int id; 	private int randomNum;
  	public MyRunnable(int id, int randomNum) { 		super(); 		this.id = id; 		this.randomNum = randomNum; 	} 	@Override 	public void run() { 		synchronized (ThreadTest.o) {	 			if (id % 2 == 0) { 				ThreadTest.g_sum += randomNum; 				ThreadTest.callBack(id, randomNum, 1);				 			} else { 				ThreadTest.g_sum -= randomNum; 				ThreadTest.callBack(id, randomNum, 0); 			} 		}
  	}
  }
  | 
 
子线程和父线程之间其实并没有进行通信,打印信息的静态回调方法callBack()虽然是在主类中定义,但是却是在子线程中调用的,而不是子线程将信息传递并通知给主线程,然后主线程打印。
 
想法二  消息队列
ThreadTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
   |  public class ThreadTest {  	public static int g_sum = 0; public static Deque<Message> messageDeque = new ArrayDeque();  	public  List<Integer> g_sumList = new ArrayList<Integer>();  	public static Object lock= new Object();    	public ThreadTest() {  		super();  		this.g_sumList.add(g_sum);  	}      	  	public  void  generateThreads(int N) {  		int randomNum;  		for (int id = 1; id <= N; id++) {  			randomNum = (int) (Math.random() * 200);  			  			MyRunnable myRunnable = new MyRunnable(id, randomNum);  			Thread t=new Thread(myRunnable);  			t.start();  		}		  	}    	public static void main(String[] args) throws InterruptedException {  		System.out.print("请输入问题规模:");  		Scanner in = new Scanner(System.in);  		int N = in.nextInt();  		ThreadTest test = new ThreadTest();  		synchronized (lock) {						  			test.generateThreads(N);				  			while(true) {  				if(messageDeque.isEmpty()) {  					lock.wait();					  				}												  				while(!messageDeque.isEmpty()) {		  					  					Message mess = messageDeque.pop();  					System.out.println("子线程"+mess.tid+"进行了"+mess.op+""+mess.randomNum+"操作,当前g_sum="+mess.g_sum);  					  					test.g_sumList.add(mess.g_sum);  					Collections.sort(test.g_sumList);  					  					System.out.println(mess.opeTime+" g_sum历史值升序为:");  					System.out.println(test.g_sumList);  					System.out.println();  				}  			}  		}  	}  }
  | 
 
MyRunnable.java
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
   | public class MyRunnable implements Runnable { 	private int tid; 	private int randomNum;
  	public MyRunnable(int id, int randomNum) { 		super(); 		this.tid = id; 		this.randomNum = randomNum; 	} 	@Override 	public void run() { 		synchronized (ThreadTest.lock) {						 			SimpleDateFormat sdf = new SimpleDateFormat();		 	        sdf.applyPattern("yyyy-MM-dd HH:mm:ss a");			 	        String opeTime = sdf.format(new Date());			 	         			if (tid % 2 == 0) { 				ThreadTest.g_sum += randomNum; 				 				 				Message message = new Message(tid, "加", randomNum,ThreadTest.g_sum,opeTime); 				ThreadTest.messageDeque.add(message); 				 				 				ThreadTest.lock.notifyAll(); 			} else { 				ThreadTest.g_sum -= randomNum; 							 				Message message = new Message(tid, "减", randomNum,ThreadTest.g_sum,opeTime); 				ThreadTest.messageDeque.add(message); 				 				ThreadTest.lock.notifyAll(); 			} 			try { 				int sleepTime = (int)(Math.random() * 500);			 				Thread.sleep(sleepTime); 			} catch (InterruptedException e) { 				e.printStackTrace(); 			} 		}
  	} 	 	 	public class Message{ 		public int tid;				 		public String op;			 		public int randomNum;		 		public int g_sum;			 		public String opeTime;		 		 		public Message(int tid, String op, int randomNum,int g_sum ,String time) { 			super(); 			this.tid = tid; 			this.op = op; 			this.randomNum = randomNum; 			this.g_sum = g_sum; 	        this.opeTime=time; 		} 		 	}
  }
  | 
 
主线程并发创建N个子线程后,转为阻塞等待状态,等待lock解锁获得执行权且消息队列非空,然后一次性打印消息队列中已经存放的消息。
子线程在进行“加减”操作完成后,创建一个消息(包含线程id、随机数、操作类型、操作结果、操作时间信息),并把这个消息添加到消息队列(一个静态全局的队列),然后Notifiy(通知)唤醒主线程,通知它消息队列有消息可以打印了。