Chinaunix首页 | 论坛 | 博客
  • 博客访问: 132170
  • 博文数量: 69
  • 博客积分: 2895
  • 博客等级: 少校
  • 技术积分: 710
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-03 18:05
文章分类

全部博文(69)

文章存档

2010年(69)

我的朋友

分类:

2010-09-15 23:18:08

jdk1.5后,提供了java.util.concurrent包,它可以实现线程池,你把线程当成普通对象就可以了,它来负责调度和执行

包括两类线程池

固定线程池

可变线程池

延迟线程池

 

固定线程池

public static ExecutorService newFixedThreadPool(int nThreads)     多任务

public static ExecutorService newSingleThreadPool()   单任务

ExecutorService 的方法

Excute(Runnablecommand);

shutdown();

用法如下

Mytask mt1=new Mytask("T1");//一个线程对象实例

ExecutorService  threadpool=Executors.newFixedThreadPool(2);

threadpool.excute(mt1);

 

可变线程池

public static ExecutorService newCachedThreadPool()    

 

延迟线程池,实现定时任务

public static ScheduledExecutorService newScheduledThreadPool(int poolSize)   

它不使用excute方法了,而是使用schedule方法

public SchedualedFuture schedule(Runnable command,long delay,TimeUnit unit);

 

有返回值的线程池

Callable接口配合Future接口,Future接口用来接受返回值

Callable接口作用同runnable接口,不过它是实现call接口方法,这个方法还有返回值

class myCallableImpl implements Callable

{

public Object call()

{

}

}

使用

ExecutorService threadpool =Executors.newSingleThreadExector();

Future f=threadpool.submit(new myCallableImpl();

 

资源封锁

前面我们知道syncnized方法可以对一段代码进行资源封锁,实际上还有很多其他方法,这里总结一下

1:synchronized

2:变量volatile

3:lock接口的实现 ReentrantLock类,它有方法:lock()、unlock(),tryLock()等,注意要try……finally,防止死锁

4:ReadWriteLock接口实现 ReentrantReadWriteLock类,方法为readLock,writeLock,使用方法大致同lock接口,不过它的效率高。也要防止死锁

5:信号量 Semaphore类,信号量不同于锁,是用来实现资源分配的,但是也有锁的特性,比如连接池,保证连接池不爆炸就可以使用这个类,主要方法为:acquire(),acquire(int n),tryAcquire(),getQueueLength(),release()

6:原子对象,在jdk15后,为了简化操作,可以把一些基本类型定义为原子对象,就单线程操作了。java.util.concurrent.atomic ,作用基本同变量volatile

7:障碍器,CyclicBarrier类,让线程同步到同一个点

 

队列和堆栈

java.util.Queue接口

public boolean offer(Object);  加入

public Object poll();   出

peek();  出,但是不删除

remove();同poll

element();同peek

add();同offer

常见实现为:java.util.LinkedList  和 java.util.PriorityQueue

BlockingQueue接口

java.util.concurrent.BlockingQueue

put(Object);进

take();出

BlockingDeque接口

它是一个阻塞的堆栈接口

putFirst(object o);

takeFirst();

putLast();

takeLast();

ReentrantReadWriteLock介绍

在java中提供了ReentrantReadWriteLock类 ,并可抽取读锁和写锁。读锁可以被多个读操作共享,并且会排斥所有写操作;写锁则互斥所有写操作和读操作。
使用读/写锁的必要步骤:

class RWDictionary {
    private final Map  m = new TreeMap();

    //1)创建ReentrantReadWriteLock对象
    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private final Lock r = rwl.readLock();//2) 抽取读锁
    private final Lock w = rwl.writeLock();//2) 抽取写锁

    public Data get(String key) {

         3) 对所有读者加锁
        r.lock(); try { return m.get(key); } finally { r.unlock(); }
    }
    public String[] allKeys() {

        3 ) 对所有读者加锁
        r.lock(); try { return m.keySet().toArray(); } finally { r.unlock(); }
    }
    public Data put(String key, Data value) {

       4) 对所有写者加锁:
        w.lock(); try { return m.put(key, value); } finally { w.unlock(); }
    }
    public void clear() {

       4) 对所有写者加锁:
        w.lock(); try { m.clear(); } finally { w.unlock(); }
    }
}

这样可以保证   a) 写者之间以及写者和读者之间互斥
                   b) 同一时间只有一个写者写,多个读者可以同时读
这样读者和写者的优先级相同,当有大量的读者和极少的写者时,写进程可能很难得到执行。所以当需要写操作优先级更高时可以设置ReentrantReadWriteLock 的策略,设置为非公平策略即可

    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(false);

把构做ReentrantReadWriteLock设为false(非公平策略)(默认为true)

公平策略:当公平地构造线程时,线程利用一个近似到达顺序的策略来争夺进入。当释放写入锁定后,将写入锁定分配给等待时间最长的单个写入者,如果有一个等待时间比所有写入者更长的读取者,则将读取锁定分配给读取者

非公平策略:当非公平地构造线程时,则不需要按照到达顺序进入锁定。不管是哪一种情况,如果读取者处于活动状态,而某个写入者进入锁定状态,那么在获取写入者并释放写入锁定之前,不会将读取锁定授予任何后续的读取者。

阅读(607) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~