程序运行原理 

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

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

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

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

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

Runnable和Callable

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

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

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;

}

}

JAVA基础复习与总结<十> Ruannable和Callable的更多相关文章

  1. Java基础复习笔记系列 八 多线程编程

    Java基础复习笔记系列之 多线程编程 参考地址: http://blog.csdn.net/xuweilinjijis/article/details/8878649 今天的故事,让我们从上面这个图 ...

  2. Java基础复习笔记系列 九 网络编程

    Java基础复习笔记系列之 网络编程 学习资料参考: 1.http://www.icoolxue.com/ 2. 1.网络编程的基础概念. TCP/IP协议:Socket编程:IP地址. 中国和美国之 ...

  3. Java基础复习笔记系列 七 IO操作

    Java基础复习笔记系列之 IO操作 我们说的出入,都是站在程序的角度来说的.FileInputStream是读入数据.?????? 1.流是什么东西? 这章的理解的关键是:形象思维.一个管道插入了一 ...

  4. Java基础复习笔记系列 五 常用类

    Java基础复习笔记系列之 常用类 1.String类介绍. 首先看类所属的包:java.lang.String类. 再看它的构造方法: 2. String s1 = “hello”: String ...

  5. Java基础复习笔记系列 四 数组

    Java基础复习笔记系列之 数组 1.数组初步介绍? Java中的数组是引用类型,不可以直接分配在栈上.不同于C(在Java中,除了基础数据类型外,所有的类型都是引用类型.) Java中的数组在申明时 ...

  6. Java基础复习笔记基本排序算法

    Java基础复习笔记基本排序算法 1. 排序 排序是一个历来都是很多算法家热衷的领域,到现在还有很多数学家兼计算机专家还在研究.而排序是计算机程序开发中常用的一种操作.为何需要排序呢.我们在所有的系统 ...

  7. 《Java基础复习》-控制执行流程

    最近任务太多了,肝哭我了,boom 参考书目:Thinking in Java <Java基础复习>-控制执行流程 Java使用了C的所有流程控制语句 涉及关键字:if-else.whil ...

  8. 《Java基础复习》—常识与入门

    突然发现自己Java基础的底子不到位,复习! 所记知识会发布在CSDN与博客网站jirath.cn <Java基础复习>-常识与入门 一.Java语言的知识体系图 分为三部分 编程语言核心 ...

  9. Java基础复习之数组

    Java基础复习之:数组 简介 数组(Array):多个相同数据类型按照一定顺序排列的集合,并使用一个名字命名,通过编号的方式对这些数据进行统一管理 一维数组 一维数组的声明与初始化 int[] id ...

随机推荐

  1. 基于jeesite的cms系统(六):Lucene全文搜索引擎

    1.lucene初始化 // @Value("${lucene.index.path}") private String indexPath = "/Users/vito ...

  2. JavaScript的Document ,Histroy,Location对象

    1.  Document对象: a)         属性: 名称 描述 alinkColor 设置或检索文档中所有活动链接的颜色 bgColor 设置或检索 Document 对象的背景色 body ...

  3. windows上安装zip版mongodb

    版本3.4:现将mongodb解压,再选择一个位置创建data文件夹并在其下创建db文件夹和log文件夹 然后编写mongod.cfg文件,注意这里用的yaml格式,对空格很敏感,并且要注意mongo ...

  4. docker使用方式

    docker使用方式安装:1.安装依赖 yum install -y yum-utils \ device-mapper-persistent-data \ lvm2 2添加yum源 yum-conf ...

  5. iTOP-4412/4418/6818开发板-fastboot烧写脚本

    在 iTOP-4412,4418,6818 开发板烧写的时候,使用的是 fastboot 工具. fastboot 工具需要在 cmd.exe 中调用,每次都需要输入烧写命令,这样步骤有点多.在程序员 ...

  6. Spring Cloud 2-Zuul 网关服务(六)

    Spring Cloud  Zuul  1.pom.xml 2.application.yml Application.java 1.pom.xml <!-- zuul 网关服务 --> ...

  7. Houdini Distributed Simulations and Render

    1.HQueue是我最早搭建到本地农场.经过测试,效率极其低下.基本上是个玩具,离真正的管理软件差的十万八千里. 不是说Hqueue不行,因为发现了用 农场管理软件API调用Houdini Rende ...

  8. Recon ASRC Conference

    场景 ASRC漏洞挖掘 方法论 1.Brands https://www.crunchbase.com/ https://en.wikipedia.org Footers & about us ...

  9. 020_Linux的孤儿进程与僵尸进程(Unix系统编程)

    1.前言 之前在看<unix环境高级编程>第八章进程时候,提到孤儿进程和僵尸进程,一直对这两个概念比较模糊.今天被人问到什么是孤儿进程和僵尸进程,会带来什么问题,怎么解决,我只停留在概念上 ...

  10. go语言中使用defer、panic、recover处理异常

    go语言中的异常处理,没有try...catch等,而是使用defer.panic.recover来处理异常. 1.首先,panic 是用来表示非常严重的不可恢复的错误的.在Go语言中这是一个内置函数 ...