jdk5.0特性/线程安全的Set/使用Callable

[b]一、JDK5特性[/b]
package jdk.jdk5;

import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**************************************
* 静态导入(static import)
*静态导入可以使被导入类的所有静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出他们的类名.
*import static package.className.staticField/staticMethod;
**********************************/

public class JDK5 {

/*************泛型(Generic)******************/
/************
* 增强了 java 的类型安全,可以在编译期间对容器内的对象进行类型检查,在运行期不必进行类型的转换。
* 而在 j2se5 之前必须在运行期动态进行容器内对象的检查及转换
***********/

//1.<ItemType>
@SuppressWarnings("serial")
public class ElementList<Element> extends LinkedList<Element> {
public void swap(int i, int j){
Element temp = this.get(i);
this.set(i, this.get(j));
this.set(j, temp);
}
}

//2.<T, V>
@SuppressWarnings("serial")
public class GenericList<T> extends LinkedList<T> {
public void swap(int i, int j){
T temp = this.get(i);
this.set(i, this.get(j));
this.set(j, temp);
}
}

//3.受限泛型是指类型参数的取值范围是受到限制的 . extends 关键字不仅仅可以用来声明类的继承关系 ,
//也可以用来声明类型参数 (type parameter) 的受限关系
public class LimitedGeneric<T extends Number> {
public double getDoubleValue(T obj){
return obj.doubleValue();
}
}

//4.泛型的通配符 "?"
public static void print(List<?> list){
String str="";
for(Iterator it=list.iterator();it.hasNext();){
str+=it.next();
}
System.out.println(str);
}

/*********************增加循环*****************************/
public static void forCycle(){
LinkedList<String> list = new LinkedList<String>();
list.add("Hi");
list.add("everyone!");
for (String s : list){
System.out.println(s);
}
}
public static void printMap(Map map) {
for (Object key : map.keySet()) {
System.out.println(key + ":" + map.get(key));
}
//不用for时
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Object key = entry.getKey();
Object value = entry.getValue();
System.out.println(key + ":" +value);
}
}

/*********************可变参数 (Variable Arguments) ******/
public static int add(int ... args){
int total = 0;
for (int i = 0; i < args.length; i++){
total += args[i];
}
return total;
}

/********************枚举类(Enumeration Classes)***********/
public enum Colors {Red, Yellow, Blue, Orange, Green, Purple, Brown, Black}
public enum Size{
SMALL("S"), MEDIUM("M"), LARGE("L"), EXTRA_LARGE("XL");
private Size(String abbreviation) { this.abbreviation = abbreviation; } //参数为缩写值
public String getAbbreviation() { return abbreviation; }
private String abbreviation;
}
public enum Operation {
PLUS { double eval(double x, double y) { return x + y; } },
MINUS { double eval(double x, double y) { return x - y; } },
TIMES { double eval(double x, double y) { return x * y; } },
DIVIDE { double eval(double x, double y) { return x / y; } };
// Do arithmetic op represented by this constant
abstract double eval(double x, double y);
}

public static void testEnumType(){
System.out.println(Colors.Red);
//在JDK5.0之前我们只能通过JOptionPane.showInputDialog进行输入,
//但在5.0中我们可以通过类Scanner在控制台进行输入操作
Scanner in = new Scanner(System.in);
System.out.print("Enter a size: (SMALL, MEDIUM, LARGE, EXTRA_LARGE) ");
String input = in.next().toUpperCase();
Size size = Enum.valueOf(Size.class, input);
System.out.println("size=" + size);
System.out.println("abbreviation=" + size.getAbbreviation());
if (size == Size.EXTRA_LARGE){
System.out.println("Good job--you paid attention to the _.");
}
System.out.println(Operation.PLUS.eval(5.0, 1.25));
}

/******
* 在JDK5.0中引入了StringBuilder类,该类的方法不是同步(synchronized)的,
* 这使得它比StringBuffer更加轻量级和有效。
*****/
public StringBuilder hql=new StringBuilder();

/*********************格式化I/O(Formatted I/O) ************/
public static void formatIO(){
int a = 150000, b = 10;
float c = 5.0101f, d = 3.14f;
System.out.printf("%4d %4d%n", a, b);
System.out.printf("%x %x%n", a, b); //十六进制
System.out.printf("%3.2f %1.1f%n", c, d);
System.out.printf("%1.3e %1.3e%n", c, d*100);
System.out.println(new Formatter().format("%08d %s \n", 5,"string").toString());

}

/*************java.util.concurrent 线程池*****************/
public class TestScheduledThread{
/**ScheduledExecutorService提供了按时间安排执行任务的功能,它提供的方法主要有:
schedule(task,initDelay):安排所提交的Callable或Runnable任务在initDelay指定的时间后执行。
scheduleAtFixedRate():安排所提交的Runnable任务按指定的间隔重复执行
scheduleWithFixedDelay():安排所提交的Runnable任务在每次执行完后,等待delay所指定的时间后重复执行。
**/
@SuppressWarnings("unchecked")
public void runScheduledThread() throws InterruptedException,ExecutionException{
//初始化一个ScheduledExecutorService对象,这个对象的线程池大小为2。
ScheduledExecutorService service=Executors.newScheduledThreadPool(2);
Runnable task1=new Runnable(){
int count=0;
public void run(){
System.out.println(new Date()+" beep"+(++count));
}
};
//直接执行,以后间隔1秒执行一次
final ScheduledFuture future1=service.scheduleAtFixedRate(task1,0,1,TimeUnit.SECONDS);
final ScheduledFuture future2=service.scheduleAtFixedRate(new Runnable(){
public void run(){
System.out.println("future2 runing!");
}
},1,2,TimeUnit.SECONDS);
ScheduledFuture future3=service.schedule(new Callable(){
public String call(){
future1.cancel(true);//取消任务
future2.cancel(true);
return "taskcancelled!";
}
},10,TimeUnit.SECONDS);
System.out.println(future3.get());
service.shutdown();//关闭服务
}
}

public static void main(String[] args){
JDK5 jdk5 = new JDK5();

/* JDK5.GenericList<String> list= jdk5.new GenericList<String>();
list.add("hello!");
list.add("world!");
print(list);
list.swap(0, 1);
print(list);

JDK5.LimitedGeneric<Integer> number = jdk5.new LimitedGeneric<Integer>();
System.out.println(number.getDoubleValue(2));

forCycle();
System.out.println(add(1,2,3,4,5));
formatIO();
testEnumType();
*/
JDK5.TestScheduledThread test = jdk5.new TestScheduledThread();
try {
test.runScheduledThread();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}

[b]二、线程安全的Set[/b]

public class TestThreadSafeSet {

final static Set<String> skipListSet = new ConcurrentSkipListSet();//jdk6
final static Set<String> arraySet = new CopyOnWriteArraySet();//jdk5

/**
* set 的元素可以根据它们的自然顺序进行排序,也可以根据创建 set 时所提供的 Comparator 进行排序,具体取决于使用的构造方法。
* 多个线程可以安全地并发执行插入、移除和访问操作。迭代器是弱一致 的,返回的元素将反映迭代器创建时或创建后某一时刻的 set 状态。
* 它们不 抛出 ConcurrentModificationException,可以并发处理其他操作。升序排序视图及其迭代器比降序排序视图及其迭代器更快。
* 请注意,与在大多数 collection 中不同,这里的 size 方法不是 一个固定时间 (constant-time) 操作。
* 由于这些 set 的异步特性,确定元素的当前数目需要遍历元素。
* 此外,批量操作 addAll、removeAll、retainAll 和 containsAll 并不 保证能以原子方式 (atomically) 执行。
*/
public static void testConcurrentSkipListSet(){
ExecutorService threadPool = Executors.newFixedThreadPool(2);

threadPool.execute(new Runnable(){
int i=1000000;
public void run() {
while(i>0){
skipListSet.add("V_"+System.currentTimeMillis());
System.out.println("Writer_"+i+": Size = " + skipListSet.size());
i--;
}
}
});

threadPool.execute(new Runnable(){
int i=1000000;int j=1;
public void run() {
while(i>0){
for(String str: skipListSet){
System.out.println("Reader_"+j+":"+str+", Size:"+skipListSet.size());
//size为遍历前的,不会实时反映,否则就是dead cycle。
}
i--;
j++;
}
}
});
}

/**
* 所有可变的操作都首先取得后台数组的副本,对副本进行更改,然后替换副本。
* 这种做法保证了在遍历自身可更改的集合时,永远不会抛出ConcurrentModificationException。
* 遍历集合会用原来的集合完成,而在以后的操作中使用更新后的集合。这些新的集合最适合于读操作通常大大超过写操作的情况
*/
public static void testCopyOnWriteArraySet(){
ExecutorService threadPool = Executors.newFixedThreadPool(2);

threadPool.execute(new Runnable(){
int i=1000000;
public void run() {
while(i>0){
arraySet.add("V_"+System.currentTimeMillis());
System.out.println("Writer_"+i+": Size = " + arraySet.size());
i--;
}
}
});

threadPool.execute(new Runnable(){
int i=1000000;int j=1;
public void run() {
while(i>0){
for(String str: arraySet){
System.out.println("Reader_"+j+":"+str+", Size:"+arraySet.size());
}
i--;
j++;
}
}
});
}

public static void main(String[] args){
testCopyOnWriteArraySet();
}

}

[b]三、Callable的使用示例[/b]

/**
* Callable、Future和FutureTask
* Callable位于java.util.concurrent包下,它也是一个泛型接口,
* call()函数返回的类型就是传递进来的V类型。
* Future提供了三种功能:1)判断任务是否完成;2)能够中断任务;3)能够获取任务执行结果。
* FutureTask是Future接口的一个唯一实现类
*/
public class JavaCallable {

public static void main(String[] args){
new JavaCallable().testCallableAndFuture();
System.out.println("########################");
new JavaCallable().testCallableAndFutureTask();
}

public void testCallableAndFuture(){
ExecutorService executor = Executors.newCachedThreadPool();
Set<Future<Integer>> resultSet = new HashSet<Future<Integer>>();

for(int i=0; i<3; i++){
CalcTask task = new CalcTask();
Future<Integer> result = executor.submit(task);
resultSet.add(result);
}
executor.shutdown();

System.out.println("main thread execute...");
try {
for(Future<Integer> result: resultSet){
System.out.println("task result " + result.get());//会阻塞,直到取到结果
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("all finished...");
}

public void testCallableAndFutureTask(){
CalcTask task = new CalcTask();
FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
Thread thread = new Thread(futureTask);
thread.start();

System.out.println("main thread execute...");
try {
System.out.println("task result = "+futureTask.get());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("all finished...");
}

private class CalcTask implements Callable<Integer>{

@Override
public Integer call() throws Exception {
Thread.sleep(1000);
int sum = 0;
for(int i=0;i<=100;i++)
sum += i;
return sum;
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值