- 浏览: 31328 次
- 性别:
- 来自: 宁波
文章分类
最新评论
-
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 816在初次运行Android程序的 ... -
再谈重入锁--ReentrantLock
2012-12-26 20:50 402重入锁(ReentrantLock)是一种递归无阻塞的同步机制 ... -
Spring 设置支态定时任务
2012-11-27 12:27 649什么是动态定时任务:是由客户制定生成的,服务端只知道 ... -
Java TCP/IP Socket 编程 笔记(四)—发送和接收数据
2012-10-29 20:17 19211.TCP/IP协议要求信息必须在块(chunk)中发送和接收 ... -
Java TCP/IP Socket 编程 笔记(三)—UDP的例子
2012-10-29 19:53 9101.UDP套接字与TCP套接字 ... -
Java TCP/IP Socket 编程 笔记(二)—TCP的例子
2012-10-29 19:49 7561.InetAddress类和SocketAddress用于 ... -
Java TCP/IP Socket 编程 笔记(一)—基本概念
2012-10-29 19:42 857一些概念: 通信信道(communication c ... -
java并发编程不得不知道的几件事(转载)
2012-10-29 19:31 646多线程编 ... -
Web.XML 配置详解
2012-09-07 11:56 578每一个站的WEB-INF下都有一个web.xml的设定文件, ... -
java 多线程编程需要注意的23条
2012-08-13 15:56 5751.多线程中有主内存和 ... -
排序算法(JAVA)(二)归并排序,堆排序,桶式排序,基数排序
2012-07-11 09:05 545六 归并排序 算法思想是每次把待排序列分成两部分,分别对这两部 ... -
排序算法(JAVA)(一)插入排序,冒泡排序,选择排序,Shell,快速排序
2012-07-11 08:59 725为了便于管理,先引入个基础类: package algor ... -
理解ThreadLocal
2012-04-28 16:05 0ThreadLocal是什么 早在JDK ... -
Java反射机制
2011-12-31 13:16 669http://www.cnblogs.com/Quincy/ ... -
Java5.0多线程编程
2011-11-22 16:00 708[size=large] Lock接口 ReentrantL ... -
Java Map遍历的方法
2011-11-09 19:41 833第一种:利用entryset遍历 Map map = ne ... -
Java常见异常汇总
2011-11-09 19:27 663转自于: http://www.javaask.com/jav ... -
java io/流
2011-11-09 19:20 482[转]JAVA IO流 http://www.blogjava ... -
Java:使用synchronized和Lock对象获取对象锁
2011-11-07 12:43 547原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 ... -
Java线程:创建与启动
2011-10-31 13:50 599一、定义线程 1、扩展 ...
相关推荐
Java Swing多线程死锁问题解析 Java Swing多线程死锁问题解析是...在实际开发中,我们需要遵循Java Swing多线程编程的基本原则,正确地使用多线程技术,避免死锁和其他问题的出现,使我们的程序更加稳定、高速和高效。
"感受Java中的多线程设计.doc" 和 "多线程编程您不知道的5件事.doc" 这两份文档可能详细阐述了Java中多线程的设计模式和最佳实践,包括同步、互斥、守护线程、线程池等概念。学习多线程不仅需要理解Thread类和...
【多线程实验】是计算机科学中的一个重要实践环节,尤其在Java编程中,多线程技术是实现并发处理和高效能应用的关键。本实验旨在帮助学生深入理解和掌握线程的相关概念,包括线程调度机制、线程同步机制,以及如何在...
《Java坦克大战:多线程与IO流的实战解析》 在编程世界中,Java以其强大的跨平台能力和丰富的库支持,成为了开发各种类型游戏的热门选择。本篇将深入探讨一款名为“坦克大战”的Java游戏,它巧妙地运用了多线程和IO...
Java内置了多线程支持,可以创建Thread对象或者使用Runnable接口来实现并发操作。 3. **事件处理**:为了响应用户的键盘输入和鼠标点击,需要设置事件监听器。Java的EventListener接口和相关的事件类,如...
课程内容涵盖了Java语言的基本概念、语法、面向对象特性、异常处理、输入输出(I/O)、图形用户界面(Swing GUI)、多线程和数据库连接(JDBC)等核心主题。 在课程中,教师通过讲述Java的发展历程,强调科技发展的曲折性...
《Java飞机大战小游戏:网络数据库线程...通过这个项目,开发者可以深入理解Java的面向对象编程、事件驱动、JDBC、Socket编程以及多线程等核心概念,同时也能感受到编程的乐趣和挑战,为今后的软件开发奠定坚实基础。
在多线程环境下,实现线程安全的单例是一个挑战,书中可能涵盖双重检查锁定(Double-Checked Locking)和静态内部类等经典实现方式。 2. **工厂方法模式**:定义一个用于创建对象的接口,让子类决定实例化哪一个类...
多线程是Java中的一个高级主题,它允许同时执行多个任务,充分利用现代多核处理器的能力。Java通过`Thread`类和`Runnable`接口支持线程的创建和管理,通过`synchronized`关键字和锁机制实现线程之间的同步和通信。 ...
一个优秀的程序员,不仅要会编写程序,更要会编写高质量的程序感受Java开发中的大智慧,让你的Java程序更优美。专 注于Java应用程序的优化方法、技巧和思想,深入剖析软件设计层面、代码层面、JVM虚拟机层面的优化...
6. 多线程:如果项目中涉及并发处理,如多个用户同时记账,那么Java的多线程技术将派上用场。Thread类和Runnable接口是实现多线程的基础。 三、项目实践 1. 设计模式:虽然项目可能较为基础,但设计模式的理念仍...
- **9.1 Java的多线程机制** - **进程与线程的区别**:解释了进程和线程的概念及其差异。 - **线程状态**:概述了Java中线程的各种状态及其转换。 - **创建线程的方法**:介绍了通过继承Thread类和实现Runnable...
同时,JAVA的内存管理和多线程支持确保了游戏运行的流畅性,使得玩家在激烈的空战中感受不到任何卡顿。 在游戏的代码结构方面,开发者注重代码的清晰性和可读性,提供了详细的注释。这不仅是对自身工作的负责,也是...
在现代软件开发中,多线程和并发控制是提升程序性能的关键技术,尤其是在服务器端开发中尤为重要。Java作为一门成熟的编程语言,其在并发控制方面提供了丰富而强大的工具和API,但是这也给开发者带来了一定的学习和...
义的应用实例,详细介绍了Java语言基础知识、面向对象程序设计、接口, 与内部类、事件监听器模型、swing图形用户界面程序设计、打包应用程序, 、异常处理、登录与调试、泛型程序设计、集合框架、多线程等内容。...
华为面试题集及感受 ...华为的面试题集及感受涵盖了JAVA基础知识、面向对象编程、多线程编程、网络编程、数据库编程、Servlet和JSP、异常处理、泛型编程和设计模式等多个方面,旨在考查应聘者的JAVA知识和编程能力。
14. **多线程**:Java支持多线程编程,理解Thread类和Runnable接口,以及同步机制如synchronized关键字和wait()、notify()方法。 15. **枚举与注解**:枚举用于定义固定的常量集合,注解提供元数据,对代码进行标记...
- 知识点的整合:设计案例平台时,需要对Java编程中复杂的概念如接口、多态性、多线程和抽象类等进行合理的整合和分类,便于学生理解和学习。 - 针对性解决学生问题:针对学生在学习过程中出现的对知识点理解不...
在Java项目实践中,电梯模拟调度算法是一个典型的多线程与图形...通过这个项目,开发者不仅可以提升对Java多线程和GUI编程的理解,还能学习到如何设计和实现复杂的调度算法,这对于开发实际的并发系统是非常有价值的。
6. **多线程**:虽然2048游戏通常不需要多线程,但如果想增加复杂性,如添加动画效果,那么可能需要使用到线程来同步UI更新和游戏逻辑。 7. **PPT介绍**:项目附带的PPT可能包含了游戏设计思路、实现步骤以及可能...