java5的并发 Collection

1:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/*
 *  第一题:
 *  现有的程序代码模拟产生了16个日志对象,
 *  并且需要运行16秒才能打印完这些日志,
 *  请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,
 *  程序只需要运行4秒即可打印完这些日志对象。
 */
public class Test1 {
	
	public static void main(String[] args){
        final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(4);
		System.out.println("begin:"+(System.currentTimeMillis()/1000));
		/*模拟处理16行日志,下面的代码产生了16个日志对象,当前代码需要运行16秒才能打印完这些日志。
		修改程序代码,开四个线程让这16个对象在4秒钟打完。
		*/
		for (int j = 0; j < 4; j++) {
			new Thread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					try {
						for(int i=0;i<4;i++){
							Test1.parseLog(Thread.currentThread().getName()
									+"----"+ queue.take());
						}
						
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
			}}).start();
		}
		for(int i=0;i<16;i++){  //这行代码不能改动
			final String log = ""+(i+1);//这行代码不能改动    
			try {
				queue.put(log);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	//parseLog方法内部的代码不能改动
	public static void parseLog(String log){
		System.out.println(log+":"+(System.currentTimeMillis()/1000));
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}		
	}
}


2:

import java.util.Map;
import java.util.Stack;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.SynchronousQueue;

/*
 * 第二题:
 * 现成程序中的Test类中的代码在不断地产生数据,
 * 然后交给TestDo.doSome()方法去处理,就好像生产者在不断地产生数据,
 * 消费者在不断消费数据。请将程序改造成有10个线程来消费生成者产生的数据,
 * 这些消费者都调用TestDo.doSome()方法去进行处理,故每个消费者都需要一秒才能处理完,
 * 程序应保证这些消费者线程依次有序地消费数据,只有上一个消费者消费完后,
 * 下一个消费者才能消费数据,下一个消费者是谁都可以,
 * 但要保证这些消费者线程拿到的数据是有顺序的。
 */
public class Test2 {
	public static void main(String[] args) {
		//final BlockingQueue b = new ArrayBlockingQueue(1);
		final Semaphore semaphore = new Semaphore(1);
		//SynchronousQueue 一个put()后等待 一个take();反之亦然
		final SynchronousQueue<String> queue = new SynchronousQueue<String>();
		System.out.println("begin:" + (System.currentTimeMillis() / 1000));
	
		for (int i = 0; i < 10; i++) {
			new Thread(){
				public void run() {
					try {
						/*时就只能有一个线程拿到许可了,而用只有1个空间的BlockQuee,
						 * 也可以阻塞其他线程
						 */
						semaphore.acquire();
						System.out.println(Thread.currentThread().getName() + "----"
								+ TestDo.doSome(queue.take()));
						semaphore.release();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}.start();
		}
		
		for (int i = 0; i < 10; i++) { // 这行不能改动
			String input = i + ""; // 这行不能改动
			try {
				queue.put(input);				
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	
	}

}

// 不能改动此TestDo类
class TestDo {
	public static String doSome(String input) {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		String output = input + ":" + (System.currentTimeMillis() / 1000);
		return output;
	}
}


3:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

/*
 *	第三题:成员key相同,则线程要互斥
 */
//不能改动此Test类	
public class Test3 extends Thread {

	private TestDoFor testDo;
	private String key;
	private String value;

	public Test3(String key, String key2, String value) {
		this.testDo = TestDoFor.getInstance();
		/*
		 * 常量"1"和"1"是同一个对象,下面这行代码就是要用"1"+""的方式产生新的对象,
		 * 以实现内容没有改变,仍然相等(都还为"1"),但对象却不再是同一个的效果
		 */
		this.key = key + key2;
		this.value = value;
	}

	public static void main(String[] args) throws InterruptedException {
		final Test3 a = new Test3("1", "", "1");
		final Test3 b = new Test3("1", "", "2");
		final Test3 c = new Test3("3", "", "3");
		final Test3 d = new Test3("4", "", "4");
		System.out.println("begin:" + (System.currentTimeMillis() / 1000));

		a.start();
		b.start();
		c.start();
		d.start();

	}
	@Override
	public void run() {
		{
			testDo.doSome(key, value);
		}

	}

	@Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		Test3 t = (Test3) obj;
		if (key.equals(t.key)) {
			return true;
		}
		return false;
	}

	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return 1;
	}

}

class TestDoFor {

	private TestDoFor() {
	}
	private static TestDoFor _instance = new TestDoFor();
	public static TestDoFor getInstance() {
		return _instance;
	}
	private CopyOnWriteArrayList keys = new CopyOnWriteArrayList();
	//private ArrayList keys = new ArrayList();
	public void doSome(Object key, String value) {
		Object o = key; 
		if (!keys.contains(o)) {
			 keys.add(o);
		} else {
			//用这个方法运行结果也可以,
		/*	for (int i = 0; i<keys.size();i++) {
				System.out.println(keys.size());
				Object oo = keys.get(i);			
				if(oo.equals(o)) {
					o = oo;
				}
			}*/
			/*
			 * 用Arraylist,迭代器在next()时,如刚好有线程 先做:keys.add(),
			 *   那么就会发生java.util.ConcurrentModificationException
			 *   
			 *   用同步集合: CopyOnWriteArrayList,就不会发生这种异常了
			 */
			for (Iterator it = keys.iterator(); it.hasNext();) {
				Object oo = it.next();
				try {
					Thread.sleep(20);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				if(oo.equals(o)) {
					o = oo;
				}
			}
		} synchronized(o)
		// 以大括号内的是需要局部同步的代码,不能改动!
		{
			try {
				Thread.sleep(1000);
				System.out.println(key+":"+value + ":"
						+ (System.currentTimeMillis() / 1000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

 

并发 Collection:

ConcurrentHashMap、CopyOnWriteArrayList 和 CopyOnWriteArraySet、CopyOnWriteArrayList :分别是HashMap、Arraylist、Set 对应的同步并发集合ConcurrentSkipListMap:有顺序的Map同步集合,可以用比较器Comparator参与构造

ConcurrentSkipListSet:有顺序的Set同步集合,可以用比较器Comparator参与构造
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值