当前位置: 首页 > news >正文

并发编程入门

并发编程一直是一个令人困惑的问题,主要的原因在于:使用并发时需要解决的问题会有很多;另外实现并发的方式不止一种,实现方式的选择也是一大问题。

谈到并发,首先稍微介绍下什么是并发,相信很多人都已经对这个概念比较熟悉,并发编程是相对顺序编程的一种新的模式。它可以一定程度的提高程序的执行速度。主要针对程序的阻塞性,因为程序的阻塞使得程序运行效率降低,而并发在一定程度上解决了程序的阻塞性带来的运行效率问题。所以也可以说,从性能的角度看,如果没有任务会阻塞,那么单处理器上的并发就没有了意义。

看起来并发也没有多大的作用噢!平常的编程工作并没有遇到很多的阻塞问题,或者涉及到并发问题。就拿Java语言来说。其实不然,Servlet对于熟悉Java的人来说再熟悉不过,而这个作为Web系统最基础的一个类天生就具有多线程性,而对并发的熟悉能使得我们充分利用这些处理器。

并发编程使得我们可以将程序划分为多个分离的、独立运行的任务,通过多线程机制,这些独立任务中的每一个都将由执行线程来驱动。一个线程就是在进程中的一个单一的顺序控制流,因此,单个进程可以拥有多个并发执行的任务,但程序使得每个任务都好像有其自己的CPU一样。其底层机制是切分CPU时间片,这些通常不需要考虑。[p653]

了解了并发相关的一些概念,接下来学习学习Java中的并发编程。

Java中Runnable代表一个任务,要实现线程行为,需要显式地将这个任务附着到线程(Thread)上,

public class BasicThreads{
    public static void main (String args[]){
        Thread t = new Thread(new LiftOff());   //LiftOff是一个任务
        t.start();
    }
}

从任务中产生返回值

Runnable是执行工作的独立任务,他不返回任何值。如果希望在任务完成时能够返回一个值,那么可以实现Callable接口而不是Runnable接口。
如何使用Callable呢?
首先Callable是一种具有类型参数的泛型,它的类型参数表示的是从方法call()中返回的值;并且必须使用ExecutorService.submit()方法调用它,示例:

public class CallableDemo {
    public static void main(String args[]){
        ExecutorService exec = Executors.newCachedThreadPool();
        ArrayList<Future<String>> results = new ArrayList<Future<String>>();
        for (int i = 0; i < 10; i++) {
            results.add(exec.submit(new TaskwithResult(i)));
        }
        for(Future<String> fs : results){
            try {
                System.out.println(fs.get());
            }catch(Exception e){
                System.out.println(e);
            }finally {
                exec.shutdown();
            }
        }
    }
}

class TaskwithResult implements Callable<String>{
    private int id ;
    public TaskwithResult(int id){
        this.id = id ;
    }
    public String call(){
        return "result of TaskWithResult " + id ;
    }
}

submit()方法会产生Future对象,它用Callable返回结果的特定类型进行了参数化,可以用isDone()方法来查询Future是否已经完成。[p659]

优先级

线程的优先级,优先级较低的只是执行的频率比较低,并不是优先级低的将不会在优先级高的线程前执行(即,优先级不会导致死锁)。
在绝大多数时间,线程的优先级都应该以默认优先级运行,试图操作线程优先级通常是一种错误。

读取线程优先级

getPriority();

修改优先级

setPriority();

让步

yield();

给线程调度机制一个暗示:工作已经差不多了,可以让别的线程使用CPU了。

但是这个暗示没有任何机制保证它会被采纳。当调用这个方法时,只是在建议具有相同优先级的其他线程可以运行。

相关文章:

  • 云时代服务器端工程师必备 CDN 技能包
  • centos6.5生产环境编译安装nginx-1.11.3并增加第三方模块ngx_cache_purge、nginx_upstream_check、ngx_devel_kit、lua-nginx...
  • DOMContentLoaded事件
  • iOS开发UITextField设置
  • 静态,抽象类、接口、类库
  • leetcode-188 买卖股票4
  • [转]理解I/O Completion Port
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • 【iOS第三方框架】FMDB刚刚好
  • C#框架及概念
  • vue webpack 构建
  • 设计模式之观察者模式(c++)
  • codeforces 492E. Vanya and Field(exgcd求逆元)
  • tcp 重发 应用层重传
  • Log4j具体使用实例
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • C++11: atomic 头文件
  • Cumulo 的 ClojureScript 模块已经成型
  • fetch 从初识到应用
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • Java比较器对数组,集合排序
  • js作用域和this的理解
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • Sass Day-01
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • tweak 支持第三方库
  • windows下使用nginx调试简介
  • 闭包--闭包之tab栏切换(四)
  • 对象引论
  • 给Prometheus造假数据的方法
  • 工程优化暨babel升级小记
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 坑!为什么View.startAnimation不起作用?
  • 悄悄地说一个bug
  • 正则表达式小结
  • 中文输入法与React文本输入框的问题与解决方案
  • #define,static,const,三种常量的区别
  • #if和#ifdef区别
  • #QT(串口助手-界面)
  • #微信小程序:微信小程序常见的配置传值
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • (1)bark-ml
  • (javascript)再说document.body.scrollTop的使用问题
  • (接口封装)
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (理论篇)httpmoudle和httphandler一览
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (三分钟)速览传统边缘检测算子
  • ****Linux下Mysql的安装和配置
  • ***利用Ms05002溢出找“肉鸡
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .NET Core跨平台微服务学习资源
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .net Stream篇(六)
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...