`
heimeiyingwang
  • 浏览: 95390 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

corejava辅导(17--3)

阅读更多

*1: 名为DoCallStuff类实现了CallableString将是call方法的返回值类型。例子中用了String,但可以是任何Java类。

*2: call方法的返回值类型为String,这是和类的定义相对应的。并且可以抛出异常。

*3: call方法可以抛出异常,如加重的斜体字所示。

以下是调用DoCallStuff的主程序。

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

public class Executor {

        public static void main(String[] args){

                //*1

                DoCallStuff call1 = new DoCallStuff(0);

                DoCallStuff call2 = new DoCallStuff(1);

                DoCallStuff call3 = new DoCallStuff(2);

                //*2

                ExecutorService es = Executors.newFixedThreadPool(3);

                //*3

                Future future1 = es.submit(call1);

                Future future2 = es.submit(call2);

                Future future3 = es.submit(call3);

                try {

                        //*4

                        System.out.println(future1.get());

                         //*5

                        Thread.sleep(3000);

                        System.out.println("Thread 2 terminated? :" + future2.cancel(true));

                        //*6

                        System.out.println(future3.get());

                } catch (ExecutionException ex) {

                        ex.printStackTrace();

                } catch (InterruptedException ex) {

                        ex.printStackTrace();

                }

        }

}

*1: 定义了几个任务

*2: 初始了任务执行工具。任务的执行框架将会在后面解释。

*3: 执行任务,任务启动时返回了一个Future对象,如果想得到任务执行的结果或者是异常可对这个Future对象进行操作。Future所含的值必须跟Callable所含的值对映,比如说例子中Future对印Callable

*4: 任务1正常执行完毕,future1.get()会返回线程的值

*5: 任务2在进行一个死循环,调用future2.cancel(true)来中止此线程。传入的参数标明是否可打断线程,true表明可以打断。

*6: 任务3抛出异常,调用future3.get()时会引起异常的抛出。

 运行Executor会有以下运行结果:

looping....

Task done. //*1

looping....

looping....//*2

looping....

looping....

looping....

looping....

Thread 2 terminated? :true //*3

//*4

java.util.concurrent.ExecutionException: java.lang.Exception: Callable terminated with Exception!

        at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:205)

        at java.util.concurrent.FutureTask.get(FutureTask.java:80)

        at concurrent.Executor.main(Executor.java:43)

        …….

*1: 任务1正常结束

*2: 任务2是个死循环,这是它的打印结果

*3: 指示任务2被取消

*4: 在执行future3.get()时得到任务3抛出的异常

lock接口

实现类ReentrantLock

我们可以用lock对象,来对临界资源加锁调用lock对象的lock()方法,使得没有得到锁的线程阻塞,解锁则调用lock对象的unlock()方法,并且释放锁,只有获得lock对象才能访问临界资源,如果没有获得lock对象,就会进入lock对象的锁池。trylock()方法会返回布尔值,这个方法是用来判断这个锁对象是不是已经被线程获取,如果返回值为true,则会直接获得这个锁对象,如果返回false,线程不会阻塞还会继续运行。

Lock lock=new ReentrantLock();

publci void test(){

   try{

          if(lock.trylock){//判断锁是否已经分配出去

lock.lock();

//如果锁没有被分配,就会获得锁,没有得到锁,就阻塞

         }else{

              ......

}

.....//需要加锁的临界资源。

     }finally{

         lock.unlock();//解锁,释放锁。

     }

}

 

ReadWriteLock读写锁接口

ReentrantReadWriteLockReadWriteLock的实现类。 

ReentrantReadWriteLockLock  readLock()方法会分配读锁对象,读锁可以分配多个线程,但是在分配读锁后所有读锁释放前,写锁是不能被分配的。

ReentrantReadWriteLockLock  writeLock()方法会分配写锁对象,且只能分配给一个线程,在分配写锁后,在写锁释放前,读锁是不能被分配。

Condition接口和实现类

Condition是等待对列的对象,它是通过lock对象的newCondition()方法得到的

Condition实现类的await()替代了wait()方法。

notify()notifyAll() JDK5.0中已经用Condition实现类的signal() signalAll()方法替换掉了,在JDK5.0中,可以使用多个等待队来存放等待的线程,并对线程进行分类。

Queue接口(Collection的子接口,队列接口)

 

LinkedList也实现了这个在JDK5.0中的新接口Queue,并且这个类自动的实现了生产者和消费者的同步。

JDK5.0的高级同步

 

Semaphore类(信号量)也就是可以向线程分配许可证,指定许可证数量可以实现多线程的同步。

Semaphore s=new Semaphore(4);

//可以分配4个许可证,许可证都被分配出去时,得不到许可证的线程就会阻塞。

Semaphore类的acquire(…)方法,获得许可证。Semaphore类的release(…) 方法,释放一个许可证,也有相应的方法指定释放和获得许可证的数量的方法。

CountDownLatch

CountDownLatch中有个计数器,访问这个类的对象就会从计数器中减一,countDown()方法会将原有的设置的计数器值减一,当countdown计数器为零时会使放所有await()的线程。

CyclicBarrier

CyclicBarrierCountDownLatch比较相似

CyclicBarrier在构造时给出线程数,只有等待的线程数到了构造方法中指定的数量,当最后一个线程等待后,所有的线程都会被释放,这个类是一个多线程汇合的工具。

Exchanger类,用exchange()方法可以使两个线程间相互交换对象,在两线程的同步点,等待第二个线程。在同步点时,交换对象,并同时被释放。

 

 

 

 

分享到:
评论
1 楼 H_eaven 2008-12-08  
博主辛苦了,总结的很好啊!
不过有的地方能多说一点儿就更完美了!
比如:
T t = new T();//是不行的.
对于泛型类型T,不能保证总会存在一个空参构造方法,因此编译器直接禁止了對象創建.
T[] tArray = new T[10];//是不行的!
這個沒找到好點兒的理由!只是编译器不让创建泛型数组.

不过博主很利害了!


相关推荐

Global site tag (gtag.js) - Google Analytics