JAVA基础复习与总结<十> Ruannable和Callable

 

程序运行原理 

1、分时调度:所有线程轮流使用CPU的使用权,平均分配给每个线程占用CPU的时间。 

2、抢占式调度:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。 

实际上,CPU使用抢占式调度模式在多个线程之间进行高速切换。对于CPU的一个核而言,某个时刻只能执行一个线程,但是CPU在多个线程之间的切换速度相对我们的感受来说很快,看上去就是在同一时刻运行。 

实际上多线程程序并不能提高程序的运行速度,但是能够提高程序的运行效率,让CPU的使用率更高。 

 

线程安全:如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。程序每次运行结果和单线程运行结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

 

 

RunnableCallable

上篇博客已经介绍了如何继承Thread来实现多线程。但是实际上直接继承Thread类有一个很大的缺点,因为java类只能单继承。当前类继承了Thread类之后就不能在继承其他类类。 

 

通过另外两种方法:RunnableCallable我们可以改进这个问题。 

 

Runnable接口

java提供了接口java.lang.Runnable来解决问题。Runnable避免单继承的局限性,便于共享资源,多个Thread可以同时加载一个Runnable。当各自Thread获得CPU时间片的时候开始运行Runnable,Runnable里面的资源是被共享的。 

使用Ruannble创建线程的过程:

 

静态代理有如下要素:

1.目标角色(真实角色)

2.代理角色

3.目标角色和代理角色实现同一接口(比如Thread作为代理角色,其接口就是Runabble

4.代理角色持有目标角色的引用

 

 

/**

* 推荐使用Runnable创建线程

* 1)避免单继承的局限性

* 2)便于共享资源

* 使用Runnable创建线程

* 1、类实现Runnable接口 + 重写 run()方法  ---->真实角色类

* 2、启动多线程使用静态代理

*   1)创建真实角色

*   2)创建代理角色 + 真实角色的引用

*   3)调用.start方法

*/

 

public class Programmar implements Runnable{ 

    public void run(){ 

        for(int i =0;i<1000;i++){ 

            System.out.println("一边敲代码...."); 

        } 

    } 

} 

 

public class ProgrammarApp { 

    public static void main(String[]args){ 

         //  1)创建真实角色 

       Programmar pro = new Programmar(); 

         //  2)创建代理角色 + 真实角色的引用 

        Thread proxy = new Thread(pro); 

         //  3)调用.start方法 

        proxy.start(); 

        //上面的start是一条路径,下面的for循环又是一条路径 

        for(int i =0;i<1000;i++){ 

            System.out.println("一边聊QQ...."); 

        } 

    } 

} 

 

 

 

Callable接口 

Runnable是执行工作的独立任务,但是它不返回任何值。如果希望任务在完成的时候能够返回一个具体的值,那么可以选择实现Callable接口而不是Runnable接口。它的参数类型表示的是从方法call()而不是run()中返回值。 

/**

*使用Callable创建线程

*/

 

public class Call { 

    public static void main(String[] args)throws InterruptedException,ExecutionException{ 

        //创建线程 

        ExecutorService ser = Executors.newFixedThreadPool(1); 

        Race tor = new Race("乌龟",1000); 

        Race rab = new Race("兔子",100); 

 

        //获取值 

        Future<Integer> result1 = ser.submit(tor); 

        Future<Integer> result2 = ser.submit(rab); 

 

        Thread.sleep(2000);//就跑两秒 

        tor.setFlag(false); 

         rab.setFlag(false);   //停止线程体循环 

 

        int  num1 = result1.get(); 

            System.out.println("乌龟跑了---->" + num1); 

 

        int  num2 = result2.get(); 

        System.out.println("兔子跑了---->" + num2); 

 

        //停止服务 

        ser.shutdown(); 

    } 

} 

class Race implements Callable<Integer>{   //后面<>里面的类型意为声明返回的是什么类型 

    private String name;   //名称 

    private long time;     //延时时间 

    private boolean flag = true; 

    private int step = 0; // 

    public Race (){ 

    } 

    public Race (String name){ 

        super(); 

        this.name = name; 

    } 

    public Race (String name,long time){ 

        super(); 

        this.name = name; 

        this.time = time; 

    } 

    public Integer call() throws Exception{ 

        while (flag){ 

            Thread.sleep(time); //延时 

            step++; 

        } 

        return step; 

    } 

    public void setName ( String name ) { 

        this.name = name; 

    } 

 

    public String getName () { 

        return this.name; 

    } 

 

    public int getStep () { 

        return this.step; 

    } 

    public void setStep ( int step ) { 

        this.step = step; 

    } 

    public long  getTime () { 

        return this.time; 

    } 

    public void setTime ( int time ) { 

        this.time = time; 

    } 

    public void setFlag ( boolean flag ) { 

        this.flag = flag; 

    } 

} 

 

 

 

 

转载于:https://www.cnblogs.com/ErictChandler/p/9609411.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值