zoukankan      html  css  js  c++  java
  • 实现线程的第三种方式

    1 实现线程前两种方式的缺点

    1) 没有返回值

    2) 不支持泛型

    3) 异常必须处理

    2.实现多线程的第三种方式

    实现 Callable 接口,重写 call 方法

    Callable 功能更加强大:

    1) Future 接 口 位 于 java.util.concurrent 包 中 ,可 以 对 具 体Runnable、Callable 任务的执行结果进行取消(cancel 方法,尝试取消执行此任务)、查询是否完成(isDone 方法)、

    取结果(get 方法,等待完成,然后检索其结果)等。  future 将来

    2) FutrueTask 是 Futrue 接口的唯一的实现类

    3) FutureTask 同时实现了 Runnable, Future 接口。它既可以作为 Runnable 被线程执行,又可以作为 Future 得到Callable 的返回值

    创建一个实现Callable接口的类

     1 import java.util.concurrent.Callable;
     2 
     3 public class MyCallable implements Callable<String> { //callable能使用泛型
     4 
     5     @Override
     6     public String call() throws Exception { //可以返回结果 抛异常
     7         String [] str={"apple","banana","orange","pear","grape"};
     8         int index=(int)(Math.random()*5); //random 随机返0到0.99 此处*5后转int则为随机返0到4
     9         return str[index];
    10     }
    11 }

    测试类

     1 import java.util.concurrent.ExecutionException;
     2 import java.util.concurrent.FutureTask;
     3 
     4 public class Test {
     5     public static void main(String[] args) throws InterruptedException, ExecutionException {
     6         //(1)创建任务
     7         MyCallable call=new MyCallable();
     8         //(2)交给任务管理 
     9         /**任务管理器是一个实现类,实现了RunnableFutrue接口,
    10          * RunnableFutrue是Futrue与Runnable接口的子接口*/
    11         FutureTask<String> task=new FutureTask<>(call); //可以看成是Runnable接口的实现类
    12         //创建代理类并启动线程
    13         Thread t=new Thread(task);
    14         t.start();
    15         System.out.println("获取结果:"+task.get());
    16         //判断任务是否执行完成
    17         System.out.println("任务是否执行完成:"+task.isDone());
    18     }
    19 }

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

    线程同步的第三种方法

    Lock 锁:对需要上锁的地方上锁

    1) JDK1.5 后新增的功能

    2) 与 Synchronized 相比,Lock 可提供多种锁方案,更灵活

    3) Java.util.concurrent.locks 中的 Lock 是一个接口,它的实现类是一个 Java 类,而不是作为语言的特性(关键字)来实现

    注意:如果同步代码有异常,要将 unLock()放到 finally 中

    步骤

    1) 创建 Lock 对象
    2) 调用 lock()方法上锁
    3) 调用 unlock()方法解锁

     1 import java.util.concurrent.locks.Lock;
     2 import java.util.concurrent.locks.ReentrantLock;
     3 
     4 public class CountRunnable implements Runnable {
     5     private int count=0;//默认值
     6     //创建一个Lock对象
     7     Lock lock=new ReentrantLock();  //Reentrant 可重入
     8     @Override
     9     public void run() {
    10         for(int i=0;i<10;i++){
    11             //synchronized (this) {
    12             try{
    13                 lock.lock();//加锁
    14                 count++;
    15                 try {
    16                     Thread.sleep(300);
    17                 } catch (InterruptedException e) {
    18                     // TODO Auto-generated catch block
    19                     e.printStackTrace();
    20                 }
    21                 System.out.println(Thread.currentThread().getName()+"执行操作:count="+count);
    22                 
    23             }finally{
    24                 //解锁
    25                 lock.unlock();
    26             }
    27             }
    28             //}
    29     }
    30 }
    View Code
     1 public class Test {
     2     public static void main(String[] args) {
     3         CountRunnable cr=new CountRunnable();
     4         //代理类的对象
     5         Thread t1=new Thread(cr,"A");
     6         Thread t2=new Thread(cr,"B");
     7         Thread t3=new Thread(cr,"C");
     8         
     9         t1.start();
    10         t2.start();
    11         t3.start();
    12         
    13     }
    14 }
    View Code

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

    Lock 与 synchronized 的区别

    1) Lock 是 显 示 锁 (手 动 开 启 和 关 闭 锁 ,别 忘 关 闭锁),synchronized 是隐式锁

    2) Lock 只有代码块锁,synchronized 有代码块锁和方法锁

    3) 使用 Lock 锁,JVM 将花费较少的时间来调度线程,性能更好,并且具有更好的扩展性(提供更多的子类)

    4) Lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。

    lock()方法会对 Lock 实例对象进行加锁,因此所有对该对象调用 lock()方法的线程都会被阻塞,直到该 Lock 对象的 unlock()方法被调用

  • 相关阅读:
    Windows共享上网的详细设置
    使用树莓派实现微信远程监控
    数据结构——队列及循环队列
    springmvc web 大文件上传源代码
    springboot web 大文件上传源代码
    jsp web 大文件上传源代码
    csharp web 大文件上传源代码
    c# web 大文件上传源代码
    .net web 大文件上传源代码
    asp.net web 大文件上传源代码
  • 原文地址:https://www.cnblogs.com/bfcs/p/10825660.html
Copyright © 2011-2022 走看看