奇数偶数分离_多线程的意义

要求: 给个list 进行奇数偶数分开,list中有1-20,20个数字。

每获得一个数字之后等待5秒,用来模拟根据这个数字进行的其他操作之后入库。(该操作与数组没有关系)

单线程:for循环 ????

package getList;

import java.util.ArrayList;
import java.util.List;

public class ForGetListNum {
	public static void main(String[] args) {
		long startTime = System.currentTimeMillis(); 
		int []lists = new int[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
		List<Integer> getLists_ou = new ArrayList<Integer>();
		List<Integer> getLists_ji = new ArrayList<Integer>();
		for (int i = 0 ; i<lists.length;i++){
			if (lists[i]%2 == 0){
				try {
					System.out.println("线程 "+ Thread.currentThread().getName()+"--模拟5秒等待中...");
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				getLists_ou.add(lists[i]);
				System.out.println("线程 "+ Thread.currentThread().getName()+"------获取元素:  "+lists[i]);
			}else{
				try {
					System.out.println("线程 "+ Thread.currentThread().getName()+"--模拟5秒等待中...");
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				getLists_ji.add(lists[i]);
				System.out.println("线程 "+ Thread.currentThread().getName()+"------获取元素:  "+lists[i]);
			}
		}
		System.out.println("  ");  
		System.out.println("线程 "+ Thread.currentThread().getName()+"  偶数集合:"+getLists_ou.toString()+"集合长度:"+getLists_ou.size());
		System.out.println("线程 "+ Thread.currentThread().getName()+"  奇数集合:"+getLists_ji.toString()+"集合长度:"+getLists_ji.size());
		long endTime = System.currentTimeMillis();  
		float seconds = (endTime - startTime) / 1000F;  
		System.out.println("  ");  
		System.out.println("                                for循环共耗时:       "+Float.toString(seconds) + " seconds.");  

	}
}

打印:

线程 main------模拟5秒等待中...
线程 main------获取元素:  1
线程 main------模拟5秒等待中...
线程 main------获取元素:  2
线程 main------模拟5秒等待中...
线程 main------获取元素:  3
线程 main------模拟5秒等待中...
线程 main------获取元素:  4
线程 main------模拟5秒等待中...
线程 main------获取元素:  5
线程 main------模拟5秒等待中...
线程 main------获取元素:  6
线程 main------模拟5秒等待中...
线程 main------获取元素:  7
线程 main------模拟5秒等待中...
线程 main------获取元素:  8
线程 main------模拟5秒等待中...
线程 main------获取元素:  9
线程 main------模拟5秒等待中...
线程 main------获取元素:  10
线程 main------模拟5秒等待中...
线程 main------获取元素:  11
线程 main------模拟5秒等待中...
线程 main------获取元素:  12
线程 main------模拟5秒等待中...
线程 main------获取元素:  13
线程 main------模拟5秒等待中...
线程 main------获取元素:  14
线程 main------模拟5秒等待中...
线程 main------获取元素:  15
线程 main------模拟5秒等待中...
线程 main------获取元素:  16
线程 main------模拟5秒等待中...
线程 main------获取元素:  17
线程 main------模拟5秒等待中...
线程 main------获取元素:  18
线程 main------模拟5秒等待中...
线程 main------获取元素:  19
线程 main------模拟5秒等待中...
线程 main------获取元素:  20
  
线程 main  偶数集合:[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]集合长度:10
线程 main  奇数集合:[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]集合长度:10
  
                                for循环共耗时:       100.008 seconds.


=======================================================================

多线程:

思路:开list.length个线程。

package getList;

import java.util.ArrayList;


public class MainClass {

	/**
	 * 要求: 给个list 进行奇数偶数分开,list中有1-20,20个数字。
		每获得一个数字,需要等待5秒,模拟根据这个数字进行的其他操作。(该操作与数组没有关系)
	 * @author yiyitadiedie
	 *
	 */
	public static void main(String[] args) throws InterruptedException {
		long startTime = System.currentTimeMillis(); 

		Lists lists = new Lists();

		ArrayList<AddNum> addNumList = new ArrayList<AddNum>();
		ArrayList<Thread> threadList = new ArrayList<Thread>();

		for (int i =0 ;i< lists.lists.length; i++){
			AddNum addNum = new AddNum(lists);
			addNumList.add(addNum);
		}
		for (int i =0 ;i<addNumList.size(); i++){
			Thread t = new Thread(addNumList.get(i));
			threadList.add(t);
		}
		for (Thread t :threadList)
			t.start();

		for (Thread t :threadList)
			t.join();

		System.out.println("  ");  
		System.out.println("线程 "+ Thread.currentThread().getName()
				+"  偶数集合:"+lists.getLists_ou.toString()+"集合长度:"
				+lists.getLists_ou.size());
		System.out.println("线程 "+ Thread.currentThread().getName()
				+"  奇数集合:"+lists.getLists_ji.toString()+"集合长度:"
				+lists.getLists_ji.size());
		long endTime = System.currentTimeMillis();  
		float seconds = (endTime - startTime) / 1000F;  
		System.out.println("  ");  
		System.out.println("                        多线程 共耗时:       "
				+Float.toString(seconds) + " seconds.");  
	}
}

package getList;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 * 待校验数组
 * @author yiyitadiedie
 *			数组lists 、getLists 模拟两张数据库表
 *			模拟5秒查询时间,得到数组中的NUM,模拟添加NUM到另一个数组
 *
 *			使用多线程的目的:每个数组元素获得之后的查询动作可以同时进行,后一个元素的查询与上一个元素查询不需要同步。
 *							即:通过多线程将这部分查询时间同时进行。
 */
public class Lists {
	/**
	 * 需要考虑同步元素
	 * 
	 * 	1. 数组本身的所有元素。			 			-------> 进程初始化载入。
	 * 					
	 * 	2. 取元素的过程同步。							-------> lock_get
	 * 			每个线程取值的下标,可以用数组的长度  - 取过的次数
	 * 					长度			:通过数组本身.length获得;
	 * 					取过的次数 	:run方法调用Lists 中的方法计数,下一个线程从Lists中获得该数。
	 * 
	 * 	3. 插入元素要同步。							-------> lock_set
	 *   插入偶数、奇数两个数组不需要同步,    --------->lock_set_ou、lock_set_ji
	 * 			如果在某个瞬间,两个进程都在往数组中插入时,就可能会产生数据丢失。
	 * 			(如果多个线程进行同一个数组插入元素操作时,必须同步。只有一个线程对一个数组插入时,不需要。)
	 * 			(数据库入库也一样,如果不等前一个insert进入,后一个insert插入,主键唯一校验就无法保证。)	
	 */
	Lock lock_get = new ReentrantLock();				// 获得元素的锁
	Lock lock_set_ou = new ReentrantLock();				// 添加偶数元素的锁
	Lock lock_set_ji = new ReentrantLock();				// 添加偶数元素的锁
	// 过滤前的数组
	int []lists  = new int[]
			{  	1, 2, 3, 4, 5, 6, 7, 8, 9,10,
			11,12,13,14,15,16,17,18,19,20};
	// 按过滤规则过滤后的存放的数组
	int getNumLength = 0;  // 每放入一个数,++一次,即 getNumLength == lists.length -1;
	List<Integer> getLists_ou = new ArrayList<Integer>(); // 放入偶数
	List<Integer> getLists_ji = new ArrayList<Integer>(); // 放入奇数
	
	public int getNum(){
		lock_get.lock();
		int i = 0;
		if (getNumLength<lists.length){//getNumLength == lists.length -1
			i = lists[getNumLength];
			getNumLength++;
			System.out.println("线程 "
			+ Thread.currentThread().getName()
			+"------获取元素:  "+i);
		}
		return i;
	}
	public void setOuNum(int Num){
		lock_set_ou.lock();
		getLists_ou.add(Num);
		System.out.println("线程 "
		+ Thread.currentThread().getName()+"-------添加完成!");
		lock_set_ou.unlock();
	}
	public void setJiNum(int Num){
		lock_set_ji.lock();
		getLists_ji.add(Num);
		System.out.println("线程 "
		+ Thread.currentThread().getName()+"-------添加完成!");
		lock_set_ji.unlock();
	}
}
package getList;

public class AddNum implements Runnable{
	private Lists lists;
	AddNum(Lists lists){
		this.lists = lists;
	}
	private int i =0;// 获取的元素
	private int threadNo1 = 0;// 获取元素后,是否完成塞值的标记。
	public void run() {
		A:while(true){
			while(lists.lists.length == lists.getNumLength){// 获取全部元素后关闭线程
				System.out.println("线程 "
						+ Thread.currentThread().getName()+" ----------------关闭" );
				break A;
			}
			while(threadNo1 ==0){
				threadNo1 = 1;
				i = lists.getNum();
				lists.lock_get.unlock();// 获得元素后,释放锁
				if(i%2==0&&i!=0){
					System.out.println("线程 "
							+ Thread.currentThread().getName()+"------模拟5秒等待中...");
					try { Thread.sleep(5000); 
					} catch (InterruptedException e) {
						e.printStackTrace();
					}				
					lists.setOuNum(i);
					threadNo1 = 0;// 完成塞值动作
				}else if(i!=0){
					System.out.println("线程 "
							+ Thread.currentThread().getName()+"------模拟5秒等待中...");
					try { Thread.sleep(5000); 
					} catch (InterruptedException e) {
						e.printStackTrace();
					}	
					lists.setJiNum(i);
					threadNo1 = 0;
				}
			}
		}
	}
}





打印:

线程 Thread-0------获取元素:  1
线程 Thread-1------获取元素:  2
线程 Thread-1------模拟5秒等待中...
线程 Thread-2------获取元素:  3
线程 Thread-0------模拟5秒等待中...
线程 Thread-2------模拟5秒等待中...
线程 Thread-4------获取元素:  4
线程 Thread-4------模拟5秒等待中...
线程 Thread-5------获取元素:  5
线程 Thread-5------模拟5秒等待中...
线程 Thread-6------获取元素:  6
线程 Thread-6------模拟5秒等待中...
线程 Thread-8------获取元素:  7
线程 Thread-8------模拟5秒等待中...
线程 Thread-9------获取元素:  8
线程 Thread-9------模拟5秒等待中...
线程 Thread-10------获取元素:  9
线程 Thread-10------模拟5秒等待中...
线程 Thread-11------获取元素:  10
线程 Thread-11------模拟5秒等待中...
线程 Thread-14------获取元素:  11
线程 Thread-14------模拟5秒等待中...
线程 Thread-16------获取元素:  12
线程 Thread-16------模拟5秒等待中...
线程 Thread-17------获取元素:  13
线程 Thread-17------模拟5秒等待中...
线程 Thread-18------获取元素:  14
线程 Thread-18------模拟5秒等待中...
线程 Thread-3------获取元素:  15
线程 Thread-3------模拟5秒等待中...
线程 Thread-13------获取元素:  16
线程 Thread-13------模拟5秒等待中...
线程 Thread-7------获取元素:  17
线程 Thread-7------模拟5秒等待中...
线程 Thread-12------获取元素:  18
线程 Thread-12------模拟5秒等待中...
线程 Thread-15------获取元素:  19
线程 Thread-15------模拟5秒等待中...
线程 Thread-19------获取元素:  20
线程 Thread-19------模拟5秒等待中...
线程 Thread-1-------添加完成!
线程 Thread-1 ----------------关闭
线程 Thread-2-------添加完成!
线程 Thread-2 ----------------关闭
线程 Thread-4-------添加完成!
线程 Thread-4 ----------------关闭
线程 Thread-0-------添加完成!
线程 Thread-9-------添加完成!
线程 Thread-9 ----------------关闭
线程 Thread-8-------添加完成!
线程 Thread-8 ----------------关闭
线程 Thread-5-------添加完成!
线程 Thread-5 ----------------关闭
线程 Thread-6-------添加完成!
线程 Thread-17-------添加完成!
线程 Thread-17 ----------------关闭
线程 Thread-11-------添加完成!
线程 Thread-11 ----------------关闭
线程 Thread-16-------添加完成!
线程 Thread-16 ----------------关闭
线程 Thread-13-------添加完成!
线程 Thread-13 ----------------关闭
线程 Thread-6 ----------------关闭
线程 Thread-0 ----------------关闭
线程 Thread-10-------添加完成!
线程 Thread-10 ----------------关闭
线程 Thread-14-------添加完成!
线程 Thread-14 ----------------关闭
线程 Thread-18-------添加完成!
线程 Thread-18 ----------------关闭
线程 Thread-3-------添加完成!
线程 Thread-3 ----------------关闭
线程 Thread-19-------添加完成!
线程 Thread-19 ----------------关闭
线程 Thread-15-------添加完成!
线程 Thread-15 ----------------关闭
线程 Thread-12-------添加完成!
线程 Thread-12 ----------------关闭
线程 Thread-7-------添加完成!
线程 Thread-7 ----------------关闭
  
线程 main  偶数集合:[2, 4, 8, 6, 10, 12, 16, 14, 20, 18]集合长度:10
线程 main  奇数集合:[3, 1, 7, 5, 13, 9, 11, 15, 19, 17]集合长度:10
  
                                 多线程 共耗时:       5.017 seconds.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值