您的位置:首页 > 其它

多线程与并发库高级应用

2014-01-03 17:41 260 查看


-------------------------------------------------------------------------------------------

Java5中的新特性-----java.util.concurrent.atomic包(用的不多):

1.对基本数据

2.对数组里的基本数据

3.对对象里的基本数据
---->java.util.concurrent.atomic.AtomicBoolean类

---->java.util.concurrent.atomic.AtomicLong类

---->java.util.concurrent.atomic.AtomicInteger类中的部分方法,可以解决多线程访问整数的问题:

public final int getAndSet(int newValue)

public final int getAndIncrement()

public final int incrementAndGet()

加1,并返回加后的值

public final int getAndDecrement()

public final int decrementAndGet()

减1,并返回减后的值

public final int getAndAdd(int delta)

public final int addAndGet(int delta)

增加并返回增加后的值,加负数就是减

public final int get()

取值

public final void set(int newValue)

赋值

---->java.util.concurrent.atomic.AtomicIntegerArray类,操作数组里的整数,

---->java.util.concurrent.atomic.AtomicIntegerFieldUpdater<T>类,操作对象里的整数,

public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass,String fieldName)

对哪个类中的哪个字段,得到类和字段的绑定,(跟反射很相似),

public int addAndGet(T obj,int delta)

得到绑定后,然后再针对某个对象,进行操作,
-------------------------------------------------------------------------------------------

Java5中的新特性-----线程池(核心功能):
---->java.util.concurrent.Executors工具类:

1.这是一个工具类,不能初始化,只有静态方法.
Executors类中的部分方法:

public static ExecutorService newFixedThreadPool(重载)

新建固定线程数量的线程池.

public static ExecutorService newCachedThreadPool(重载)

新建缓存线程池,线程池内的线程的个数是不定的.

public static ExecutorService newSingleThreadExecutor(重载)

新建单一线程池,如果线程死了,还会再创建一个新线程.

public static ScheduledExecutorService newScheduledThreadPool(重载)

新建指定线程数量的调度线程池.
Executor(接口)

     |--ExecutorService(接口)

             |--ScheduledExecutorService(接口)
---->java.util.concurrent.Executor接口中的方法:

void execute(Runnable command)

每执行一次,就向线程池中的线程提交一个任务,每个任务又是一个Runnable接口.
---->java.util.concurrent.ExecutorService接口:

这个接口,就相当于一个线程池.
ExecutorService接口中的方法:

void shutdown()

执行以前的任务,不接受新的任务,关闭.

List<Runnable> shutdownNow()

不接受新的任务,暂停等待的任务,并返回等待的任务列表.

<T> Future<T> submit(Callable<T> task)

返回任务等待完成的Future.
---->java.util.concurrent.ScheduleExecutorService接口:

此接口不支持Timer类中的具体时间点的调度,需要自己写,写法参见此接口的说明文档.
ScheduleExecutorService接口中的方法:

void execute(Runnable command)

继承自Executor接口中的方法.

<V> ScheduledFuture<V> schedule(Callable<V> callable,long delay,TimeUnit unit)

ScheduledFuture<?> schedule(Runnable command,long delay,TimeUnit unit)

此方法相当于Timer类中的schedule方法.

ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit)

此方法相当于Timer类中周期执行的schedule方法
---->java.util.concurrent.TimeUnit枚举:

表示时间单位的枚举.
案例:

对各种线程池,进行测试.

代码:

// ExecutorService threadPool = Executors.newFixedThreadPool(2);

// ExecutorService threadPool = Executors.newCachedThreadPool();

ExecutorService threadPool = Executors.newSingleThreadExecutor();

for (int j = 0; j < 5; j++) // 线程池中有2个线程,提交了5个任务.

{

 final int task = j; // 突破final的限制

 threadPool.execute(new Runnable()

 {

  @Override

  public void run()

  {

   for (int i = 0; i < 10; i++)

   {

    try

    {

     Thread.sleep(20);

    } catch (InterruptedException e)

    {

     e.printStackTrace();

    }

    System.out.println(Thread.currentThread().getName()

      + "----进度" + i + "---任务" + task);

   }

  }

 });

}

System.out.println("任务提交完成!");

threadPool.shutdown(); // 完成提交任务后,结束程序.

// threadPool.shutdownNow(); //将触发上面的InterruptedException.

ScheduledExecutorService scheduledPool = Executors

  .newScheduledThreadPool(2);

scheduledPool.scheduleAtFixedRate(new Runnable()

{

 @Override

 public void run()

 {

  System.out.println("bombing...");

 }

}, 3, 2, TimeUnit.SECONDS);
看点:

通过技巧,突破final的限制.

-------------------------------------------------------------------------------------------

Java5中的新特性-----Callable与Future的应用(很实用的功能):

可使一个线程监测另一个线程的运行,并获得线程执行完成后的结果.
---->java.util.concurrent.Callable<V>接口:

表示对线程的结果进行回调.
Callable<V>接口中的方法:

V call() throws Exception
---->java.util.concurrent.Future<V>接口:

1.表示线程期望得到的结果.

2.它会一直等待,直到线程运行完毕并返回结果.
Future<V>接口中的方法:

boolean cancel(boolean mayInterruptIfRunning)

boolean isCancelled()

boolean isDone()

V get() throws InterruptedException,ExecutionException

这是一个阻塞式方法,一直等待,直到拿到结果为止.

V get(long timeout,TimeUnit unit) throws InterruptedException,ExecutionException,TimeoutException

在一定时间内等待,如果超时还没拿到结果,抛TimeoutException.
---->java.util.concurrent.CompletionService<V>接口:
CompletionService<V>接口中的方法:

Future<V> submit(Callable<V> task)

Future<V> submit(Runnable task,V result)

Future<V> take() throws InterruptedException

Future<V> poll()

Future<V> poll(long timeout,TimeUnit unit) throws InterruptedException
---->java.util.concurrent.ExecutorCompletionService<V>类:

1.这个类实现了上面的CompletionService<V>接口.

2.这个类中的方法,与实现的接口中的方法,完全一样.
ExecutorCompletionService<V>类中的方法:

public Future<V> submit(Callable<V> task)

public Future<V> submit(Runnable task,V result)

public Future<V> take() throws InterruptedException

每执行一次,就等待并得到一个运行完成的Future.

public Future<V> poll()

public Future<V> poll(long timeout,TimeUnit unit) throws InterruptedException
案例:

举例得到另外一个线程完成的反馈,再做进一步处理.

ExecutorService threadPool = Executors.newSingleThreadExecutor();

Future<String> future =
4000
threadPool.submit(new Callable<String>()

{

 @Override

 public String call() throws Exception

 {

  Thread.sleep(2000);

  return "完活";

 }

});

System.out.println("等待完活");

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

//System.out.println(future.get(1,TimeUnit.SECONDS));  //这个方法抛出TimeoutException

//threadPool.shutdownNow();   //这样就不报异常了.
案例:

同时种了几块麦地,哪个先熟了,则先去收割哪块麦子.

ExecutorService threadPool = Executors.newFixedThreadPool(3);

CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool);

for (int i = 0; i < 100; i++)  //一次性提交了100个任务.

{

 final int seq = i;    //使final可赋值的技巧.

 completionService.submit(new Callable<Integer>()

 {

  @Override

  public Integer call() throws Exception

  {

   Thread.sleep(new Random().nextInt(500));

   return seq;

  }

 });

}

System.out.println("等待完活");

for (int i = 0; i < 100; i++)  //收获这100个任务.

{

 Future<Integer> future = completionService.take();

 System.out.println("任务"+future.get()+"完活了");

}

System.out.println("所有任务都完活了");

threadPool.shutdownNow();  //这样就不报异常了.

-------------------------------------------------------------------------------------------

Java5中的新特性-----更新的锁模型(核心功能):
传统的锁模型:

关键字synchronized和方法wait,notify都是绑定在同一把锁(Object)对象之上的,不能实现更加精细的线程控制.

Object

   |--synchronized

           |--wait

           |--notify
改进的锁模型:

方法wait和notify不再直接绑定在synchronized关键字所绑定的对象上,而是绑定在了Condition对象上,这就可以实现更加精细的控制.

Lock

   |--Condition

           |--wait

           |--notify

   |--Condition

           |--wait

           |--notify
---->java.util.concurrent.locks.Lock接口:

void lockInterruptibly() throws InterruptedException

boolean tryLock()

void lock()

上锁

Condition newCondition()

boolean tryLock(long time,TimeUnit unit) throws InterruptedException

void unlock()

解锁
---->java.util.concurrent.locks.ReentrantLock类:

这个类实现了Lock接口.

---->java.util.concurrent.locks.Condition接口:

void await() throws InterruptedException

void awaitUninterruptibly()

long awaitNanos(long nanosTimeout) throws InterruptedException

boolean await(long time,TimeUnit unit) throws InterruptedException

boolean awaitUntil(Date deadline) throws InterruptedException

void signal()

void signalAll()

---->java.util.concurrent.locks.ReadWriteLock接口:

Lock readLock()

Lock writeLock()

----------------------------------------------------------------------------------------------------

Java5中的新特性----读写锁:

1.多个读锁不互斥.

2.读锁与写锁互斥,写锁与写锁互斥.
类中的哪些代码是读,哪些代码是写,都是人工指定的,
 
 
 
 
----------------------------------------------------------------------------------------------------------

案例:

设计一个缓存系统.
----------------------------------------------------------------------------------------------------------


         
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: