• Java n个线程轮流打印数字的问题



    一. 实现两个线程。轮流打印出数字。例如以下:

    bThread --> 10
    aThread --> 9
    bThread --> 8
    aThread --> 7
    bThread --> 6
    aThread --> 5
    bThread --> 4
    aThread --> 3
    bThread --> 2
    aThread --> 1

    用java中的Lock类实现:

    package com.yjq.thread_demo;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class TwoThreadPrinter {
    
    	private Lock threadLock = new ReentrantLock();
    
    	private boolean flag = false;
    	
    	int count =10;
    
    	Thread aThread = new Thread(new Runnable() {
    		public void run() {
    			while (true) {
    					// 锁定
    					threadLock.lock();
    					try {
    						if ( count < 1) {
    							return;
    						}
    						if (flag) {
    							// aThread的任务
    							System.out.println("aThread --> " + (count--));
    							flag = !flag;
    						}
    					} catch (Exception e) {
    						// TODO: handle exception
    					} finally {
    						// 释放锁
    						threadLock.unlock();
    					}
    				}
    		}
    	});
    
    	Thread bThread = new Thread(new Runnable() {
    		public void run() {
    			while (true) {
    					// 锁定
    					threadLock.lock();
    					try {
    						if ( count < 1) {
    							return;
    						}
    						if (!flag) {
    							// aThread的任务
    							System.out.println("bThread --> " + (count--));
    							flag = !flag;
    						}
    					} catch (Exception e) {
    						// TODO: handle exception
    					} finally {
    						// 释放锁
    						threadLock.unlock();
    				}
    			}
    		}
    	});
    
    	public void startTwoThread() {
    		aThread.start();
    		bThread.start();
    	}
    
    	public static void main(String[] args) {
    		TwoThreadPrinter twoThreadPrinter = new TwoThreadPrinter();
    		twoThreadPrinter.startTwoThread();
    	}
    
    }
    


    用synchronized实现:

    package com.yjq.thread_demo;
    
    public class TwoThreadPrinter2 {
    	
    
    	
    private Object threadLock = new Object();
    
    	int count =10;
    
    	Thread aThread = new Thread(new Runnable() {
    		public void run() {
    			while (true) {
    					// 锁定
    					synchronized (threadLock) {
    						if ( count < 1) {
    							return;
    						}
    
    //							// aThread的任务
    							System.out.println("aThread --> " + (count--));
    
    						threadLock.notify();
    						try {
    							threadLock.wait();
    						} catch (Exception e) {
    							// TODO: handle exception
    						}
    					}
    				}
    		}
    	});
    
    	Thread bThread = new Thread(new Runnable() {
    		public void run() {
    			while (true) {
    					// 锁定
    					synchronized (threadLock) {
    						if ( count < 1) {
    							return;
    						}
    
    //							// aThread的任务
    							System.out.println("bThread --> " + (count--));
    
    						threadLock.notify();
    						try {
    							threadLock.wait();
    						} catch (Exception e) {
    							// TODO: handle exception
    						}
    					}
    				}
    		}
    	});
    
    	public void startTwoThread() {
    		aThread.start();
    		bThread.start();
    	}
    
    	public static void main(String[] args) {
    		TwoThreadPrinter twoThreadPrinter = new TwoThreadPrinter();
    		twoThreadPrinter.startTwoThread();
    	}
    
    }
    


    用Lock类的方法比較easy理解。 lock() 和 unlock()之间的块是被锁定的


    用synchronize的方法少用了个flag来标志轮到哪个线程来打印,这是由于线程锁的notifity( )方法会释放锁并唤醒其它线程 ,线程锁的wait( )方法则是释放锁并休眠当前线程,假设刚好仅仅有两个线程,那么自然就是開始还有一个线程而休眠本线程。


    二.扩展到n个线程轮流打印数字的问题


    n个线程轮流打印数字。用Lock类是比較easy扩展的


    比方三个线程轮流打印数字

    package com.myexample.test;
    
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class ThreeThreadPrinter {
    
    	private Lock threadLock = new ReentrantLock();
    
    	private int flag = 0;
    	
    	int count =10;
    
    	Thread aThread = new Thread(new Runnable() {
    		public void run() {
    			while (true) {
    					// 锁定
    					threadLock.lock();
    					try {
    						if ( count < 1) {
    							return;
    						}
    						if (count%3 == 0 ) {
    							// aThread的任务
    							System.out.println("aThread --> " + count);
    							count--;
    						}
    					} catch (Exception e) {
    						// TODO: handle exception
    					} finally {
    						// 释放锁
    						threadLock.unlock();
    					}
    				}
    		}
    	});
    
    	Thread bThread = new Thread(new Runnable() {
    		public void run() {
    			while (true) {
    					// 锁定
    					threadLock.lock();
    					try {
    						if ( count < 1) {
    							return;
    						}
    						if (count%3 == 1 ) {
    							// aThread的任务
    							System.out.println("bThread --> " + count);
    							count--;
    						}
    					} catch (Exception e) {
    						// TODO: handle exception
    					} finally {
    						// 释放锁
    						threadLock.unlock();
    				}
    			}
    		}
    	});
    
    	Thread cThread = new Thread(new Runnable() {
    		public void run() {
    			while (true) {
    					// 锁定
    					threadLock.lock();
    					try {
    						if ( count < 1) {
    							return;
    						}
    						if (count%3 == 2 ) {
    							// aThread的任务
    							System.out.println("cThread --> " + count);
    							count--;
    						}
    					} catch (Exception e) {
    						// TODO: handle exception
    					} finally {
    						// 释放锁
    						threadLock.unlock();
    				}
    			}
    		}
    	});
    	
    	public void startTwoThread() {
    		aThread.start();
    		bThread.start();
    		cThread.start();
    	}
    
    	public static void main(String[] args) {
    		ThreeThreadPrinter twoThreadPrinter = new ThreeThreadPrinter();
    		twoThreadPrinter.startTwoThread();
    	}
    
    }
    

    输出结果

    bThread --> 10
    aThread --> 9
    cThread --> 8
    bThread --> 7
    aThread --> 6
    cThread --> 5
    bThread --> 4
    aThread --> 3
    cThread --> 2
    bThread --> 1



  • 相关阅读:
    (转)交换两个变量的值,不使用第三个变量的四种法方
    Java权威编码规范
    Git的安装和设置
    ActiveMQ简单入门
    JMS术语
    求助 WPF ListViewItem样式问题
    初步探讨WPF的ListView控件(涉及模板、查找子控件)
    圆角button
    用Inno Setup来解决.NetFramework安装问题
    [!!!!!]Inno Setup教程-常见问题解答
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/7095993.html
Copyright © 2020-2023  润新知