- 浏览: 7339772 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1546)
- 企业中间件 (236)
- 企业应用面临的问题 (236)
- 小布Oracle学习笔记汇总 (36)
- Spring 开发应用 (54)
- IBatis开发应用 (16)
- Oracle基础学习 (23)
- struts2.0 (41)
- JVM&ClassLoader&GC (16)
- JQuery的开发应用 (17)
- WebService的开发应用 (21)
- Java&Socket (44)
- 开源组件的应用 (254)
- 常用Javascript的开发应用 (28)
- J2EE开发技术指南 (163)
- EJB3开发应用 (11)
- GIS&Mobile&MAP (36)
- SWT-GEF-RCP (52)
- 算法&数据结构 (6)
- Apache开源组件研究 (62)
- Hibernate 学习应用 (57)
- java并发编程 (59)
- MySQL&Mongodb&MS/SQL (15)
- Oracle数据库实验室 (55)
- 搜索引擎的开发应用 (34)
- 软件工程师笔试经典 (14)
- 其他杂项 (10)
- AndroidPn& MQTT&C2DM&推技术 (29)
- ActiveMQ学习和研究 (38)
- Google技术应用开发和API分析 (11)
- flex的学习总结 (59)
- 项目中一点总结 (20)
- java疑惑 java面向对象编程 (28)
- Android 开发学习 (133)
- linux和UNIX的总结 (37)
- Titanium学习总结 (20)
- JQueryMobile学习总结 (34)
- Phonegap学习总结 (32)
- HTML5学习总结 (41)
- JeeCMS研究和理解分析 (9)
最新评论
-
lgh1992314:
[u][i][b][flash=200,200][url][i ...
看看mybatis 源代码 -
尼古拉斯.fwp:
图片根本就不出来好吧。。。。。。
Android文件图片上传的详细讲解(一)HTTP multipart/form-data 上传报文格式实现手机端上传 -
ln94223:
第一个应该用排它网关吧 怎么是并行网关, 并行网关是所有exe ...
工作流Activiti的学习总结(八)Activiti自动执行的应用 -
ZY199266:
获取不到任何消息信息,请问这是什么原因呢?
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息 -
xiaoyao霄:
DestinationSourceMonitor 报错 应该导 ...
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息
反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,当在一个线程对象上调用stop()方法时,这个线程对象所运行的线程就会立即停止,假如一个线程正在执行:synchronized void { x = 3; y = 4;} 由于方法是同步的,多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到x = 3;时,被调用了 stop()方法,即使在同步块中,它也干脆地stop了,这样就产生了不完整的残废数据。而多线程编程中最最基础的条件要保证数据的完整性,所以请忘记线程的stop方法,以后我们再也不要说“停止线程”了。而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果 很难检查出真正的问题所在。
suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此 时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就 会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用 wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非(a)“醒来”的线程具有更高的优先级,(b)正在运行的线程因为其它原因而阻塞。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,释放当前线程锁定的任何对象。进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。 sleep()方法是本地方法,属于Thread类,它有两种定义: public static native void sleep(long millis) throws InterruptedException; public static void sleep(long millis, int nanos) throws InterruptedException { //other code } 其中的参数millis代表毫秒数(千分之一秒),nanos代表纳秒数(十亿分之一秒)。这两个方法都可以让调用它的线程沉睡(停止运行)指定的时间,到了这个时间,线程就会自动醒来,变为可运行状态(RUNNABLE),但这并不表示它马上就会被运行,因为线程调度机制恢复线程的运行也需要时间。调用sleep()方法并不会让线程释放它所持有的同步锁;而且在这期间它也不会阻碍其它线程的运行。上面的2个方法都声明抛出一个 InterruptedException类型的异常,这是因为线程在sleep()期间,有可能被持有它的引用的其它线程调用它的 interrupt()方法而中断。中断一个线程会导致一个InterruptedException异常的产生,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及以后的代码。 为了更好地理解interrupt()效果,我们来看一下下面这个例子: public class InterruptTest { public static void main(String[] args) { Thread t = new Thread() { public void run() { try { System.out.println("我被执行了-在sleep()方法前"); // 停止运行10分钟 Thread.sleep(1000 * 60 * 60 * 10); System.out.println("我被执行了-在sleep()方法后"); } catch (InterruptedException e) { System.out.println("我被执行了-在catch语句块中"); } System.out.println("我被执行了-在try{}语句块后"); } }; // 启动线程 t.start(); // 在sleep()结束前中断它 t.interrupt(); } } 运行结果: 我被执行了-在sleep()方法前 我被执行了-在catch语句块中 我被执行了-在try{}语句块后 wait()方法也是本地方法,属于Object类,有三个定义: public final void wait() throws InterruptedException { //do something }
1) sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
2) sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会。
public class ThreadTest implements Runnable{
public void run(){
for(int k=0;k<10;k++){
if(k == 5 && Thread.currentThread().getName().equals("t1")){
Thread.yield();
}
System.out.println(Thread.currentThread().getName()+ " : " + k);
}
}
public static void main(String[] args) {
Runnable r = new ThreadTest();
Thread t1 = new Thread(r,"t1");
Thread t2 = new Thread(r,"t2");
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
}
}
输出结果:
t1 : 0
t1 : 1
t1 : 2
t1 : 3
t1 : 4
t1 : 5
t1 : 6
t1 : 7
t1 : 8
t1 : 9
t2 : 0
t2 : 1
t2 : 2
t2 : 3
t2 : 4
t2 : 5
t2 : 6
t2 : 7
t2 : 8
t2 : 9
多次运行这个程序,输出也是一样。这说明:yield()方法不会使不同优先级的线程有执行的机会。
isInterrupted()和interrputed()方法的区别 isInterrupted方法是实例方法,interrupted方法是静态方法。 Thread.currentThread().isInterrupted() Thread.interrupted() 首先说明:wait(),notify(),notifyAll()这些方法由java.lang.Object 类提供,而上面讲到的方法都是由java.lang.Thread 类提供(Thread类实现了Runnable 接口)。wait(),notify(),notifyAll()这三个方法用于协调多个线程对共享数据的存取,所以必须在synchronized 语句块内使用这三个方法。先看下面了例子: 示例12: public class ThreadTest implements Runnable{ public static int shareVar = 0; public synchronized void run(){ if(shareVar == 0){ for(int i=0;i<10;i++){ shareVar++ ; if(shareVar == 5){ try{ this.wait(); }catch(Exception e){} }} } if(shareVar != 0){ System.out.print(Thread.currentThread().getName()); System.out.println(" shareVar = " + shareVar); this.notify(); } } public static void main(String[] args){ Runnable r = new ThreadTest(); Thread t1 = new Thread(r,"t1"); Thread t2 = new Thread(r,"t2"); t1.start(); t2.start(); }} 运行结果: t2 shareVar = 5 t1 shareVar = 10 t1线程最先执行。由于初始状态下shareVar 为0,t1 将使shareVar 连续加1,当shareVar的值为5 时,t1 调用wait()方法,t1 将处于休息状态,同时释放锁标志。这时t2 得到了锁标志开始执行,shareVar 的值已经变为5,所以t2 直接输出shareVar 的值,然后再调用notify() 方法唤醒t1。t1 接着上次休息前的进度继续执行,把shareVar 的值一直加到10,由于此刻shareVar 的值不为0,所以t1 将输出此刻shareVar的值,然后再调用notify()方法,由于此刻已经没有等待锁标志的线程,所以此调用语句不起任何作用。
wait()->本线程进入等待队列,只能通过别的线程的notify()或notifyall()唤醒 notify()->随机地从等待队列删除一个线程,也就是说,该线程进入执行状态 notifyall()->删除所有在等待队列中的线程,按线程的优先级执行 不推荐使用notify():因为这是随机地从等待队列中取一个线程执行,我们不能通过设定优先级进行控制,如果,随机抽取的线程不能往前执行,这就有可能产生死锁,所以,建议使用notifyall() 如: class MyThread extends Thread{ Test t = new Test(); public void run(){ t.test(); System.out.println("Thread say:Hello,World!"); } public class Test { int x = 0; public void test(){ if(x==0) try{ wait();}catch(Exception e){} } } public static void main(String[] args) throws Exception{ new MyThread().start(); } } 结果这个线程就不会进入t的wait方法而直接打印出Thread say:Hello,World!.而如果改成: public class Test { int x = 0; public synchornized void test(){ if(x==0) try{ wait(); }catch(Exception e){} } public static void main(String[] args) throws Exception{ new MyThread().start(); } } 我们就可以看到线程一直等待,注意这个线程进入等待后没有其它线程唤醒,除非强行退出JVM环境,否则它一直等待.所以请记住:[线程要想调用一个对象的wait()方法就要先获得该对象的监视锁,而一旦调用wait()后又立即释放该锁]。 public class ThreadA{ public static void main(String[] args){ ThreadB b=new ThreadB(); b.start(); //这里只是将线程b处于可运行状态,并不会立刻执行,实际上是先执行主线(进)程,再去执行线程b,如果主线程运行时间过长的话,则会在期间执行b。 System.out.println("b is start...."); synchronized(b){ //定义一个同步块,使用b作为资源锁。对于wait方法必须有的 try{ System.out.println("Waiting for b to complete..."); b.wait();//临时释放锁,并阻塞当前线程。让其他使用同一把锁的线程ThreadB有机会执行。 注意:直接写wait()是不对的。 System.out.println("waiting...."); }catch(InterruptedException e){} } System.out.println("Total is :"+b.total); } } class ThreadB extends Thread{ int total; public void run() { System.out.println("ThreadB is running ...."); synchronized(this){ //必须有 System.out.println("ThreadB is excuting for statement.."); for(int i=0;i<5;i++){ total+=i; System.out.println("total is "+total); } notify(); //在已经获得了一个对象的锁的前提下,调用notify()会通知线程调度程序,唤醒其它等待这个锁的线程队列中的线程,notifyAll()唤醒所有这类线程。 } //end for synchronized } } 运行结果: b is start.... Waiting for b to complete... ThreadB is running .... ThreadB is excuting for statement.. total is 0 total is 1 total is 3 total is 6 total is 10 waiting.... Total is :10
程序中必须同时满足以下四个条件才会引发死锁: 互斥(Mutual exclusion):线程所使用的资源中至少有一个是不能共享的,它在同一时刻只能由一个线程使用。 持有与等待(Hold and wait):至少有一个线程已经持有了资源,并且正在等待获取其他的线程所持有的资源。 非抢占式(No pre-emption):如果一个线程已经持有了某个资源,那么在这个线程释放这个资源之前,别的线程不能把它抢夺过去使用。 循环等待(Circular wait):假设有N个线程在运行,第一个线程持有了一个资源,并且正在等待获取第二个线程持有的资源,而第二个线程正在等待获取第三个线程持有的资源,依此类推……第N个线程正在等待获取第一个线程持有的资源,由此形成一个循环等待。 举例: 1.未发生死锁 public class Test { static Object o1 = new Object();//静态对象 static Object o2 = new Object(); public static void main(String[] args) { synch synch1 = new synch(); synch synch2 = new synch(); synch1.a=0; synch2.a=2; Thread t1 = new Thread(synch1); Thread t2 = new Thread(synch2); t1.start(); t2.start(); } }//Test类结束 class synch implements Runnable{ int a; public void run() { System.out.println(a); if(a == 0){ try { synchronized (Test.o1) {//对类Testt中的静态对象同步 Thread.sleep(500); } //synchronized是对o1的对象锁,500毫秒以后会释放掉对o1的锁,所以不会发生死锁 synchronized (Test.o2) { System.out.println("aaaa"); } } catch (InterruptedException ex) {} }else try { synchronized (Test.o2) { Thread.sleep(500); } synchronized (Test.o1) { System.out.println("aaba"); } } catch (InterruptedException ex) {} } } 运行后显示 0 2 aaba aaaa 没有发生死锁 2.发生了死锁 修改如下: public void run() { System.out.println(a); if(a == 0){ try { synchronized (Test.o1) { //已获取o1对象锁 Thread.sleep(500); System.out.println("Try to get o2"); synchronized (Test.o2) { //未释放o1(同步块中的语句执行完以后才释放该对象的锁),尝试获取o2,被挂起 System.out.println("aaaa"); } } } catch (InterruptedException ex) {} } else { try { synchronized (Test.o2) { //已获取o2的对象锁 Thread.sleep(500); System.out.println("Try to get o1"); synchronized (Test.o1) { //未释放o2,尝试获取o1,也被挂起,死锁 System.out.println("aaba"); } } } catch (InterruptedException ex) {} } } 结果: 0 2 Try to get o2 Try to get o1 另一个例子: class Friendly { private Friendly partner; private String name; public Friendly(String name) { this.name = name; } public synchronized void hug() { System.out.println(Thread.currentThread().getName()+" in " + name + ".hug() trying to invoke " + partner.name +".hugBack()"); partner.hugBack(); } private synchronized void hugBack() { System.out.println(Thread.currentThread().getName()+" in " + name + ".hugBack()"); } public void becomeFriend(Friendly partner) { this.partner = partner; } public static void main(String[] args) { final Friendly jareth = new Friendly("jareth"); final Friendly cory = new Friendly("cory"); jareth.becomeFriend(cory); cory.becomeFriend(jareth); new Thread(new Runnable() { public void run() { jareth.hug(); } }, "Thread1").start(); new Thread(new Runnable() { public void run() { cory.hug(); } }, "Thread2").start(); } } 结果: Thread1 in jareth.hug() trying to invoke cory.hugBack() Thread1 in cory.hugBack() Thread2 in cory.hug() trying to invoke jareth.hugBack() Thread2 in jareth.hugBack()
发表评论
-
【转】Coherence Event Processing by using Map Trigger Feature
2013-06-25 14:02 2084This article shows how to proc ... -
【转】Distributed Data Management in Oracle Coherence
2013-06-25 13:55 1894This article shows how to prov ... -
【转】How to distribute Spring Beans by using Coherence
2013-06-21 17:24 1972转载自: http://www.onli ... -
关于H2使用的那些事
2012-12-14 16:40 27222在项目中采用H2作为工 ... -
【转】ConcurrentHashMap之实现细节
2012-12-10 14:32 1776Conc ... -
【转】Java并发编程J.U.C之Condition
2012-12-10 13:14 1914转载自http://www.golde ... -
【转】Java并发编程J.U.C之锁的获取与释放
2012-12-10 13:07 1617转载自 http://www.g ... -
【转】JUC 基础内容概述
2012-12-10 13:01 2050Concurrent Programming in Jav ... -
【转】Java并发编程之ConcurrentHashMap
2012-12-10 12:56 1778ConcurrentHashMap Conc ... -
【转】单例模式完全解析
2012-12-07 12:58 1710本文将探讨单例模式的各种情况,并给出相应的建议。 单例模式应该 ... -
【转】JAVA并发容器代码随读
2012-12-06 15:29 2954转载自 http://rdc.taobao.c ... -
【转】Spring 事务管理高级应用难点剖析:
2012-12-04 16:29 2230转载自 http://www.ibm.com/deve ... -
【转】Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式
2012-12-04 15:11 4484转载自 http://downpour.ite ... -
Hibernate延迟加载和OpenSessionInView
2012-12-03 17:13 3172ThreadLocal& ... -
关于ThreadLocal分析和总结
2012-12-03 15:56 1864什么是ThreadLocal? ... -
【转】java线程阻塞中断和LockSupport的常见问题
2012-12-03 13:30 1793转载自 http://www.iteye ... -
java 中 ReentrantReadWriteLock的读锁和写锁的使用
2012-11-30 17:14 10441jdk文档中关于Reentr ... -
java 多线程中Semaphore信号量
2012-11-30 15:39 3755Semaphore信号量: 可以维护当前 ... -
Java 文件锁的使用
2012-11-30 13:21 4438多线程-内部锁、重进入 多线程 ... -
【转】线程安全与锁优化
2012-11-29 16:17 1890转载自http://xussen.iteye.com/blo ...
相关推荐
"一点课堂 JAVA核心知识点整理.zip"这个压缩包文件包含了关于Java编程的关键概念和技能的详细总结,非常适合初学者和有经验的开发者进行学习和复习。 首先,Java的核心知识点包括基础语法。这包括变量声明、数据...
Java提供了Thread类和Runnable接口来实现多线程,同时JavaFX也提供了Task和Service类来更方便地处理FX应用程序中的后台任务。 7. **事件驱动编程**: JavaFX基于事件驱动模型,用户与界面的交互(如点击按钮)会触发...
Java提供了Thread类和Runnable接口来创建多线程程序。 以上便是根据提供的Java练习题库内容整理出的知识点概述,掌握了这些基础知识点,对进一步学习Java的高级特性和开发实际应用程序都有很大帮助。
### Java基础知识大总结 #### 一、基础概念与特性 1. **Null的打印结果**:在Java中,如果尝试打印一个null值的对象引用,输出结果将会是`null`。 2. **字符串常量的拼接问题**:当在字符串中出现如`'10'`这样的...
Java的线程机制可以帮助你实现这一点,如创建Thread类的子类或者使用Runnable接口。 6. **IO流**:用于读写数据,如保存和加载火车信息、用户购票记录等。Java的FileInputStream和FileOutputStream可以用来读写文件...
标签也进一步确认了这一点,同样显示为"Java code Java code"。下面我们将详细讨论Java编程语言的关键知识点,并可能在这些文件中找到的相应内容。 1. **Java基础知识**:Java是一种面向对象的、跨平台的编程语言,...
`Thread`或`Runnable`接口可用于实现这一点。 4. **用户界面(UI)设计**:如果程序具有图形用户界面,可能需要使用Java Swing或JavaFX来创建按钮、进度条等控件,实现与用户的交互。 5. **事件监听**:在UI中,...
"java入门非常的浅显易懂"这个标题暗示了我们将要探讨的内容是针对新手的Java基础知识,而描述中的“很好的入门书”进一步确认了这一点,意味着我们将深入浅出地讲解Java的基本概念。 1. **Java简介**:Java是由Sun...
以上是Java技术500篇可能涉及的主要知识点,每一点都值得深入学习和实践,以提升你的Java编程能力。在实际开发中,还需要结合设计模式、最佳实践以及不断涌现的新技术和框架,如Spring Boot、MyBatis、Docker、...
1. **Java多线程基础知识**:Java多线程允许程序同时执行多个任务,这是通过创建和管理线程实现的。Java提供了两种创建线程的方式:继承Thread类和实现Runnable接口。线程的状态包括新建、就绪、运行、阻塞和终止,...
Java通过内置的Thread类和它的子类来支持多线程编程,提供了一套丰富的API来处理多线程环境下的复杂问题。 Java语言的另一个重要特性是安全性。Java通过字节码验证器以及类加载器来保证应用程序的安全性。字节码...
Java的Thread类和ExecutorService可以帮助实现这一目标。 8. **事件处理**:Java的事件监听机制使得播放器能够响应用户的操作,如点击播放按钮或调整音量滑块。 9. **资源管理**:播放器需要有效地管理内存和系统...
这个“java程序设计课件”为那些已经有一定Java基础的学习者提供了深入学习和巩固知识的机会。课件中不仅涵盖了Java的基础知识,还涉及了如何实现数据库连接,这是在实际项目开发中非常实用的一项技能。 首先,Java...
Java的EventListener接口和相关类可以帮助我们实现这一点。 5. **算法**:游戏规则的实现需要算法支持,比如洗牌算法、判断胜败的逻辑等。 6. **IO流**:如果游戏有保存和加载功能,那么文件输入输出流...
《JAVA解惑》这本书主要针对...以上是《JAVA解惑》一书中可能涉及的部分知识点,每一点都值得深入学习和实践。通过掌握这些内容,开发者可以更好地解决Java编程中的各种问题,提升编程技能,写出更高效、更可靠的代码。
本资源“java学习笔记”源自B站上的黑马程序员Java教学课程,虽然没有图片辅助,但通过文本资料,我们可以深入理解Java的核心概念和关键知识点。 首先,Java的学习通常从基础语法开始,包括变量、数据类型、运算符...
- **知识点**: 在Java中,通过继承`Thread`类来创建线程的方式之一。 - **选项分析**: - A、`classA4 extends Thread`: 正确的继承方式,但缺少`run()`方法实现。 - B、`classA4 implements Thread`: 错误,因为`...
Java的Thread类和Runnable接口可以帮助你实现这一点。同时,线程同步也是需要注意的问题,以避免多个线程间的冲突。 6. **资源管理**:音乐文件和其他资源的加载和释放是资源管理的一部分。理解如何正确地打开、...
总的来说,通过分析和实现这两个Java小游戏,初学者可以巩固理论知识,提升编程技能,并逐渐培养解决实际问题的能力。这是一个很好的学习路径,不仅能激发学习兴趣,也有助于理解Java编程的精髓。希望这个资源对你的...
在Java中,我们可以使用`while(true)`循环来实现这一点,并通过`Thread.sleep()`方法控制游戏的帧率,以确保游戏流畅运行。 接下来,我们来看看图形用户界面(GUI)的构建。Java提供了`java.awt`和`javax.swing`包...