- 浏览: 29893 次
- 性别:
- 来自: 宁波
文章分类
最新评论
-
zpd00001:
大道理,刚毕业的菜鸟们是不懂的- -!!
毕业后五年之内将决定你的一生 人生与励志 -
li_47195:
看完后我沉默很久..所谓“优秀生”?..一篇转载,献给所有和我一样迷茫没有目标的人
我就不说最初那个单核CPU时代了,我们从多进程编程开始讲。在引入多线程概念前,多进程是并发编程的唯一解决方案;多进程在解决并发问题的同时带来了一些问题:主要有以下几点,多线程也就是正因为多进程有许多不足才被设计出来: 多进程的特点:每个进程都独立拥有数据空间(堆、栈、代码区等),这是多线程跟多进程最本质的区别,这个区别是多线程与多进程优缺点的起因 结论:多线程是不能完全替换多进程,但多线程带来的革命也是明显的,我程序设计中,我们要跟据实际情况,选择合理的并发方案;其实好多时候,我们往往是两者结合来用。好了,对多线程的基本概念讲到这里,我们以下要讲讲Java对多线程的支持。 如果Java不是一门面象对象语言,那么我们要学习的东西可能少得多,但使用起来并不一定方便。我们先来讲一下Java中多线程的设计。Java中一切都是对像,线程也是,线程是CPU调度的单位,它本身跟具体的程序功能无关;所以Java把程序的功能又独立提取出来,放到Runnable或Callable接口中;最后Java添加了一个管理类ExecotorSerivce,用于管理多个线程的执行。 一个Thread类表示一个线程,其实一个线程可以抽象为一个程序指针,保存了程序当前的执行进度;当然,其实一个线程的实现相对复杂,还包括锁的实现等,这个说法仅供理解。 一个thread对象包含了一些关键信息 线程执行的具体功能被放在这个接口类里,如果涉及到资源协作(锁或是synchronized),我一般不直接在这两个类里处理这些,因为Runnable及Callable是两个行为类,一般不在这两个类里直接包含资源,所以一般不涉及到资源的锁问题;这样做也是为了让自己的程序更加容易阅读;然而一般退出线程的逻辑却应放在这个类里。 Callable相对于Runnable给我们带来了两个额外功能 线程返回结果其实在绝大多数情况下其它是没必要的,但这种情况也不算太少数;我想说明的是,相对于Runnable来说Callable并没有带来革命性的更改,所以喜欢优先用哪个,我们可以跟据需要来;我一般会优先用Runnable+ExecutorSerivce;因为即使突然发现需要返回值,把Runnable修改为Callable也不是一件复杂的事。 相对于Callable,我觉得这个类实用多了;这类有以下特点: 异常是与线程对应的,我们知道当主线程抛出uncatched异常时,会造成jvm挂掉,并打印出栈信息。虽然这个功能也就这样,但至少我们知道自己的程序已经出状况了,需要重新维护。 子线程默认不会通知uncached异常信息,出现异常时,子线程挂掉,但我们什么也不知道。我们可以通过以下方法来外理这种异常 设置守护线程方法 有这样一些线程,它们仅给其它线程提供后台服务,它们独立存在的话没有任何意义,我们往往把它们设置为守护线程;我们再说一点,一个Java进程都对应一个运行时的jvm,那么什么时候决定这个java进程已经执行完了可以退出jvm呢?回答是除了守护线程之外已经没有其它线程了,换句话说,程序已经不对外执行计算任务了,那么这个时候进程就可以结束了。 优先级 优先级仅是CPU调度的一个指标,其实影响CPU调度的原因很多。知道这点就可以了。 线程是CPU调度的基本单位,一个线程可以用以下方法直接影响CPU调度,且不涉及到资源及锁。CPU协调就是一般说的CPU竞争,我觉得用协调更好一些,因为现在我们程序员的素质高,不会占着CPU不放了;不像一些软件,比如,卡巴死机。 sleep原理:创建并启动一个闹钟,并传入回调(回调用于继续执行),然后挂起当前线程;sleep并不释放锁,所以尽量不要在获得锁的时候用sleep,那就是占着茅坑不...了,呵呵。 暂停当前线程,使其它线程能获得cpu。 多线程真正有意思的地方我想就是这部分了,我们程序员不是干体力活的;这部分是最能体现我们程序员实力的地方了。 多线程里有句老话,大致这个意思:一切多线程问题的根源是对共享数据的访问。这句话绝对是95%正确的。5%我忽略不计了,算买个保险吧。 Java中多线程间的资源共享是通过“互斥锁”来实现的,它分为两种语法: 在讲具体锁之前,我想先讲两个非常重要的,但实际使用时很少使用(至少我是这样的) 原子性 理解原子性的概念非常重要。原子性指一个操作是CPU执行的最小单位,不能被打断。对具有原子性的操作,原理上讲我们是不用给它们加锁的。 volatile关键字作用 Java线程一般会把共享变量等拷贝一份副本到线程“本地栈”,从而提高性能;拷由的时机往往是这样的:在获得锁时拷贝,在释放锁的时候写回(包含wait,notify前后那些隐藏的锁交换); 用volatile修饰的变量表示这样一个意思:不对共享变量进行拷贝,直接访问共享变量,以达到变量值的一致性。 实站:我们很难确定一个操作的原子性,这往往跟不同的JVM实现有关;举两个例子:i++,不是原子的。即使long l=5;这样一个操作在一个32位机子上也不是原子的,我们知道java中的长整型应该是64位的,而32位机器一次仅能处理32位,那么有可能,这个一赋值操作会分为两个原子操作,先赋低32位,再赋高32位。当然如果操作系统做了特殊处理的话,那另当别论。关于volatile也一样,即使加了volatile我们还得考虑原子性,而原子性往往是得不到保障的,所以volatile的使用也比较难。 我觉得一般的做法是不要考虑这两个概念,尽量给共享的资源加上锁。即使在我们认为是原子操作的地方也加上锁,因为原子操作往往非常“精细”,锁定的时间间隔自然也相对较短。 先说一下锁的概念:一个目标锁同时仅能被一个线程占用,线程要访问锁之间的代码的话必须先获取锁;(这里先不考虑特殊的ReadWriteLock) 每个java对象都对应有一个monitor。synchronized就是通过锁定这个monitor对象来达到锁定的目的;相对于显式的lock,synchronized语法的最大好处应该是会自动释放锁。synchronized有以下三种用法 相对于用synchronized方法及语句,Lock提供了更加灵活的、可扩展的锁操作。它提供了更加灵活的语法结构,有的(指Lock的实现类)可能拥有一些特性,如它有可能支持多个与之关联的 Condition 对象 synchronized方式的一些不足 synchronized方法及语句提供了访问隐藏锁的方法,每个对象都关联着一个隐藏锁,但限制了锁的获得及释放必须发生在一个块状结构里:当同时获得多个锁时,这些锁必须以相反的顺序释放,而且,所有的锁的释放与锁的获取必须在同一个文法范围(可以理解为同一层缩进,同一个方法,同一个块里)。 虽然syncronized方法及语句的块式机制让我们能够轻松地运用隐藏锁机制来进行多线程编程,并且让我们避免了锁编程中的一些普遍编程问题。但还是有一些情况你不得不使用更加灵活的Lock方式(显式的Lock)。 一个必须得用显式Lock的实例 比如:一些并行遍历数据结构的算法,需要一种“一步步地”或“链接式的锁定”:先获得节点A的锁,再获得节点B的锁,然后释放对A的锁,获得对C的锁,释放对B的锁,再获得对D的锁 ...。Lock接口的实现类就能够让这些技法的使用变为可能,它实现了让锁能在不同的块结构里获得并释放,并允许多个锁可以以任何顺序获得或释放。 显式锁的特点(还是与实现类有关,并不是说每种显式锁都一定支持这些特点): 继承结构 java.util.concurrent.locks.Lock `-ReentrantLock `-ReentrantReadWriteLock `-ReadLock `-WriteLock 说实话,我不知道他这里为什么要把类名取为Reentrant(可重入),我觉得这根本与可重入的概念没有什么关系。有关可重入的概念大家要以自行从网上搜索。 wait概念 由于程序执行需要的资源没有达到程序要求,而主动放弃已经获得的对象锁(在synchronized里对象指的是monitor),此时线程进入目标对象(monitor)的等待队列,让其它线程准备完资源后再重新通知锁定的对象(monitor),并让对象(monitor)进一步通知在等待队列里的线程。 notify & notifyAll 一般情况下,我们都用nofityAll(),它会通知所有等待的线程,都去尝试获得锁;而notify();仅会从等待队列中挑选一个线程,如果被挑选的线程,但如果被挑选的线程此时并没有满足执行的条件,进入wait,那么就可能造成所有的线都都进入了wait状态。 锁的目标对象与资源的关系 其实两者并没有直接的关系,但目标对象的选择必需与想要锁定的资源在逻辑上要能大约等同。这个在Java语言里比较好选择,一般把资源封装在对象里,然后把对象(或对象的monitor)当成目标对象。 比如:LocalThread<Integer> locThd = ...;做为一个共享变量的话,它会自动为每个线程自动创建一份拷贝,线程与线程内的数据不影响。这个类在线程内传递参数非常有用,我们可以把一个线程需要的一些公共信息放在LocalThread里。 这个是个很有意思的话题,网上有一些终止线程的方法,比如判断标记,用interrupt中断,也有说中断并不能用来终止线程;那么到底是怎么回事? 线程是没法直接强制终止的 直接强制终止一个线程,会造成数据的丢失,不一致等,这对一个程序来说是非常致命的,所以Java里希望线程都能够“主动退出”; 判断标记的缺点 判断标记法自然是终止线程的一个可行的方法,但有一个不足:当线程被堵塞时(sleep, wait, join)线程无法进入判断,更无法即时退出;尤其是当线程进入DeadLock时,就更没有办法了。 再说说interrupt interrupt有两个作用,一个是给线程添加interrupt标记,另一个是终止正被堵塞的线程,并让它们抛出一个InterruptedException,抛出interruptException之后,线程会自动清除interrupt标记。interrupt虽然不能直接退出所有线程,但至少当前已经堵塞的线程能立马退出,那些未堵塞的线程也能比较顺利地进入一个“判断标记”,然后自动退出线程。所以总的来说,结合interruptException来退出线程是很不错的,也可以直接用isInterrupt()函数来获取interrupt标记直接判断,其它判断标记的添加可以以语镜为准。 如果你使用是的ExecutorService,那么,有两个方法与线程关闭相关 多进程缺点:
多进程优点:
Java多线程
线程对象设计
Thread类
Runnable & Callable类
ExecutorService管理类
异常处理
Thread.UncaughtExceptionHandler eh = new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
// TODO Auto-generated method stub
}
};
t.setUncaughtExceptionHandler(eh); //一个线程对应一个异常控制器
Thread.setDefaultUncaughtExceptionHandler(eh); //默认所有线线程都用这个异常控制器
其它:守护线程及优先级
t.setDaemon(true);//请注意顺序
t.start();
守护线程概念
CPU协调
sleep()方法
Thread.sleep(millsec); //让当前线程sleep一会
Yield()方法
Thread.yield();
资源协调
原子性 & volatile关键字
块状隐式锁synchronized
显式锁Lock
wait & notify & notifyAll;
线程式局部变量
终止线程
来个实例
发表评论
-
【转】PC安卓模拟器PANIC: Could not open:C:\Documents and Settings\Administrator\.android
2013-03-13 23:43 749在初次运行Android程序的 ... -
再谈重入锁--ReentrantLock
2012-12-26 20:50 363重入锁(ReentrantLock)是一种递归无阻塞的同步机制 ... -
Spring 设置支态定时任务
2012-11-27 12:27 616什么是动态定时任务:是由客户制定生成的,服务端只知道 ... -
Java TCP/IP Socket 编程 笔记(四)—发送和接收数据
2012-10-29 20:17 18651.TCP/IP协议要求信息必须在块(chunk)中发送和接收 ... -
Java TCP/IP Socket 编程 笔记(三)—UDP的例子
2012-10-29 19:53 8791.UDP套接字与TCP套接字 ... -
Java TCP/IP Socket 编程 笔记(二)—TCP的例子
2012-10-29 19:49 7301.InetAddress类和SocketAddress用于 ... -
Java TCP/IP Socket 编程 笔记(一)—基本概念
2012-10-29 19:42 797一些概念: 通信信道(communication c ... -
java并发编程不得不知道的几件事(转载)
2012-10-29 19:31 617多线程编 ... -
Web.XML 配置详解
2012-09-07 11:56 552每一个站的WEB-INF下都有一个web.xml的设定文件, ... -
java 多线程编程需要注意的23条
2012-08-13 15:56 5501.多线程中有主内存和 ... -
排序算法(JAVA)(二)归并排序,堆排序,桶式排序,基数排序
2012-07-11 09:05 516六 归并排序 算法思想是每次把待排序列分成两部分,分别对这两部 ... -
排序算法(JAVA)(一)插入排序,冒泡排序,选择排序,Shell,快速排序
2012-07-11 08:59 697为了便于管理,先引入个基础类: package algor ... -
理解ThreadLocal
2012-04-28 16:05 0ThreadLocal是什么 早在JDK ... -
Java反射机制
2011-12-31 13:16 638http://www.cnblogs.com/Quincy/ ... -
Java5.0多线程编程
2011-11-22 16:00 681[size=large] Lock接口 ReentrantL ... -
Java Map遍历的方法
2011-11-09 19:41 808第一种:利用entryset遍历 Map map = ne ... -
Java常见异常汇总
2011-11-09 19:27 633转自于: http://www.javaask.com/jav ... -
java io/流
2011-11-09 19:20 453[转]JAVA IO流 http://www.blogjava ... -
Java:使用synchronized和Lock对象获取对象锁
2011-11-07 12:43 516原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 ... -
Java线程:创建与启动
2011-10-31 13:50 567一、定义线程 1、扩展 ...
相关推荐
另外 ,作为一种面世较晚的语言,Java也集中体现和充分利用了当代软件技术新成果,如面 向对象、多线程等,这些也都在它的特点中有所反映。 1.开台无关性 如前所述,Java语言独特的运行机制使得它具有良好的二进制级...
一个优秀的程序员,不仅要会编写程序,更要会编写高质量的程序感受Java开发中的大智慧,让你的Java程序更优美。专 注于Java应用程序的优化方法、技巧和思想,深入剖析软件设计层面、代码层面、JVM虚拟机层面的优化...
另外,作为一种面世 较晚的语言,Java 也集中体现和充分利用了当代软件技术新成果,如面向对象、多线程等,这些 也都在它的特点中有所反映。 1.开台无关性 如前所述,Java 语言独特的运行机制使得它具有良好的二进制...
义的应用实例,详细介绍了Java语言基础知识、面向对象程序设计、接口, 与内部类、事件监听器模型、swing图形用户界面程序设计、打包应用程序, 、异常处理、登录与调试、泛型程序设计、集合框架、多线程等内容。...
义的应用实例,详细介绍了Java语言基础知识、面向对象程序设计、接口, 与内部类、事件监听器模型、swing图形用户界面程序设计、打包应用程序, 、异常处理、登录与调试、泛型程序设计、集合框架、多线程等内容。...
义的应用实例,详细介绍了Java语言基础知识、面向对象程序设计、接口, 与内部类、事件监听器模型、swing图形用户界面程序设计、打包应用程序, 、异常处理、登录与调试、泛型程序设计、集合框架、多线程等内容。...
游戏中的坦克和子弹等元素都被抽象为对象,通过多线程实现了游戏的动态效果,使得玩家可以感受到真实的战斗氛围。 在游戏设计中,碰撞检测和移动逻辑起着重要的作用。玩家的坦克需要及时做出反应,避开敌方坦克和...
[Java多线程概览.md](./ profession / program / java /并发编程/ Java多线程概览.md) 测试 openCV Python Django的 烧瓶 [python基础学习.md](./ profession / program / python / python基础学习.md) ...
采用java编写,运用多线程,实现飞机射击游戏,游戏一共三个关卡,每个关卡都有boss,最后一个boss有激光效果。游戏可选择难度,可选择声音开关,游戏过程中有gift,吃到后可增加子弹数目,游戏设计了三种不同的敌机...
编程思想的转变是困难的, 我在读这本书的时候, ...原本在 Java 中非常复杂的多线程、分布式处理方式, 在 Elixir 中变得无比简单, 这也是 Elixir 在现代 IT 系统中的价值:最大化 CPU 的处理能力。
Guava是一种基于开源的Java库,从源码查看感受到其标准简洁以及对代码有高度的优化。避免了开发过程中充分造轮子。 通过查看源码可以学习到“设计模式运用”,“工具类方法的编写规范”,“代码性能优化”,“最佳实践...
AI核心为:将当前局面看作根进行递归搜索,建立搜索树,每次为搜索点打分,利用极大极小算法剪枝优化搜索范围、置换表优化搜索效率、多线程优化搜索时间,找出最佳落子点,甚至必胜态。 由此可知,递归层数越多,越...
Windows 98和Windows NT都是支持32位优先权式多任务(preemptive multitasking)及多线程的图形操作系统。Windows拥有图形使用者接口(GUI ),这种使用者界面也称作「可视化接口」或「图形窗口环境」。有关GUI的概念...
读核感悟 伪装现场 内核线程: 17 读核感悟 伪装现场 信号通信 19 读核感悟 kbuild系统 内核模块的编译 22 读核感悟 kbuild系统 编译到内核和编译成模块的区别 24 读核感悟 kbuild系统 make bzImage的过程 26 读核...
·介绍被认为是标准C++下一版特征之一的多线程处理编程技术,并提供最新研究成果 ·对书中包含的所有示例代码都提供免费下载,这些代码段经过多个软件平台和编译器(包括基于Windows/Mac/Linux的GNU C++编译器) 的...
如何解决ACCESS中SELECT TOP语句竟然返回多条记录的问题? Asp.net 利用OleDb的GetOLEDBSchemaTable方法得到数据库架构信息 用于 Visual Studio .Net 的 IBM DB2 开发外接程序 第2章 并发操作的一致性问题 (2) Using...
免责声明:这是一个有趣的项目,没有在实验设计中投入太多。 有些结果显然是有缺陷的。 哲学 简单的解决方案优先:每种语言的第一个实现应该是解决问题的非优化、幼稚或惯用的尝试。 这允许感受一种语言的开箱即用...