thread相关http://blog.csdn.net/forwayfarer/article/details/3455130

  1.sleep()和wait()
        这两个方法都可以让调用它的线程沉睡(sleep)/停止运行(wait)指定的时间,到了这个时间,线程就会自动醒来,变为可运行状态(RUNNABLE)。

public static native void sleep(long millis) throws InterruptedException;   
        public static void sleep(long millis, int nanos) throws InterruptedException

public final void wait() throws InterruptedException
        public final native void wait(long timeout) throws InterruptedException;   
        public final void wait(long timeout, int nanos) throws InterruptedException

Parameters:
        millis - the length of time to sleep in milliseconds.毫秒数
        nanos - 0-999999 additional nanoseconds to sleep.纳秒数

调用sleep()方法并不会让线程释放它所持有的同步锁;而且在这期间它也不会阻碍其它线程的运行。
        当调用了某个对象的wait()方法时,当前运行的线程就会转入WAITING状态,等待别的线程再次调用这个对象的notify()或者notifyAll()方法唤醒它,或者到了指定的最大等待时间,线程自动醒来。如果线程调用了某个对象的wait()方法,这个线程就会释放这个对象所持有的同步资源(不会释放其他对象的同步锁)。jdk api doc:The current thread must own this object‘s monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object‘s monitor to wake up either through a call to the notify method or the notifyAll method

  1. package edu.hust.test;
  2. public class ThreadSleep implements Runnable {
  3. /*
  4. * 让线程睡眠的理由很多,比如(1)认为该线程运行得太快,需要减缓一下,以便和其他线程协调;(2)查询当时的股票价格,每睡5分钟查询一次,可以节省带宽,而且即时性要求也不那么高。
  5. * 注意:时间的精确性。线程醒来之后不会马上运行,而要等待cpu给其分配时间片。因此sleep()中指定的时间并不是线程不运行的精确时间!所以不能依赖sleep()方法提供十分精确的定时。
  6. * 我们可以看到很多应用程序用sleep()作为定时器,实际是不精确的。
  7. *
  8. *
  9. * Thread.sleep(5 * 1000)和Thread.currentThread().sleep(5 * 1000)没区别:都表示让当前线程sleep 5秒.
  10. * 一个是通过类获取静态方法,一个是通过实例对象获得静态方法(sleep()为静态方法).
  11. *
  12. * 注意:sleep并不是Thread的一个STATE
  13. */
  14. public void execute() {
  15. synchronized(this) {
  16. try {
  17. System.out.println(Thread.currentThread().getName() + ", sleep()前");
  18. Thread.sleep(1000);
  19. System.out.println(Thread.currentThread().getName() + ", sleep()后");
  20. } catch (InterruptedException e) {
  21. System.out.println(Thread.currentThread().getName() + ", 谁把我吵醒了.....");
  22. }
  23. //此处如果使用System.err, 会有很意外的结果。System.out和System.err的区别请见blog
  24. System.out.println(Thread.currentThread().getName() + ", run()结束..进入TERMINATED状态");
  25. }
  26. }
  27. public void run() {
  28. execute();
  29. }
  30. public static void main(String[] args) throws InterruptedException {
  31. ThreadSleep threadSleep = new ThreadSleep();
  32. Thread[] threads = new Thread[5];
  33. System.out.println(Thread.currentThread().getName() + "线程的状态为:" + Thread.currentThread().getState());
  34. for (Thread thread : threads) {
  35. thread = new Thread(threadSleep);
  36. thread.start();
  37. if ("Thread-1".equals(thread.getName()) || "Thread-3".equals(thread.getName()))
  38. thread.interrupt();
  39. }
  40. }
  41. /*
  42. * 某次运行结果:
  43. * main线程的状态为:RUNNABLE
  44. * Thread-1, sleep()前
  45. * Thread-1, 谁把我吵醒了.....
  46. * Thread-1, run()结束..进入TERMINATED状态
  47. *
  48. * Thread-3, sleep()前
  49. * Thread-3, 谁把我吵醒了.....
  50. * Thread-3, run()结束..进入TERMINATED状态
  51. *
  52. * Thread-0, sleep()前
  53. * Thread-0, sleep()后
  54. * Thread-0, run()结束..进入TERMINATED状态
  55. *
  56. * Thread-2, sleep()前
  57. * Thread-2, sleep()后
  58. * Thread-2, run()结束..进入TERMINATED状态
  59. *
  60. * Thread-4, sleep()前
  61. * Thread-4, sleep()后
  62. * Thread-4, run()结束..进入TERMINATED状态
  63. *
  64. * 从运行结果可以得出很多结论, 其中之一是:调用sleep()方法并不会让线程释放它所持有的同步锁;而且在这期间它也不会阻碍其它线程的运行。
  65. *
  66. * */
  67. }
  1. package edu.hust.test;
  2. class MyThread1 implements Runnable {
  3. private Object obj;
  4. public MyThread1(Object o) {
  5. obj = o;
  6. }
  7. public void run() {
  8. synchronized (obj) { //这里是给obj对象(也就是str="爱吃土豆")加锁, 如写成synchronized (this), 则表示是给myThread1加锁.
  9. try {
  10. System.out.println("MyThread1进入wait状态");
  11. obj.wait();
  12. System.out.println("MyThread1被notify");
  13. } catch (InterruptedException e) {
  14. System.err.println("谁把我吵醒了.....");
  15. }
  16. }
  17. }
  18. }
  19. class MyThread2 implements Runnable {
  20. private Object obj;
  21. public MyThread2(Object o) {
  22. obj = o;
  23. }
  24. public void run() {
  25. synchronized (obj) {  //这里是给obj对象(也就是str="爱吃土豆")加锁, 如写成synchronized (this), 则表示是给myThread2加锁.
  26. System.out.println("MyThread2调用notify()方法");
  27. obj.notify();
  28. }
  29. }
  30. }
  31. public class ThreadWait {
  32. public static void main(String[] args) {
  33. //错误的写法, 这里myThread1和myThread2操作的是两个不同的对象.
  34. //Thread myThread1 = new Thread(new MyThread1(new String("爱吃土豆")));
  35. //Thread myThread2 = new Thread(new MyThread2(new String("爱吃土豆")));
  36. //正确的写法, 这里myThread1和myThread2操作的是同一个对象.
  37. String str = "爱吃土豆";
  38. Thread myThread1 = new Thread(new MyThread1(str));
  39. Thread myThread2 = new Thread(new MyThread2(str));
  40. myThread1.start();
  41. myThread2.start();
  42. }
  43. /*
  44. * 运行结果:
  45. * MyThread1进入wait状态
  46. * MyThread2调用notify()方法
  47. * MyThread1被notify
  48. *
  49. * 这里使用了synchronized块来包装某个实例对象(String str = "爱吃土豆")的wait()和notify()方法, 这是由于调用这两个方法的时候线程必须获得同步锁.
  50. * 如果synchronized包装的不是同一个实例对象的wait()和notify()方法, 则表示给wait()和notify()加的锁不是同一把锁,eg:将synchronized(lock)改为synchronized(this).
  51. * 将会抛出java.lang.IllegalMonitorStateException, 告诉你current thread not owner.
  52. *
  53. * */
  54. /*
  55. * 摘录:
  56. * 多线程常用的一些方法: wait(),wait(long),notify(),notifyAll()
  57. * wait()      是使持有对象锁的线程释放锁;
  58. * wait(long)  是使持有对象锁的线程释放锁时间为long(毫秒)后,再次获得锁,wait()和wait(0)等价;
  59. * notify()    是唤醒一个正在等待该对象锁的线程,如果等待的线程不止一个,那么被唤醒的线程由jvm确定;
  60. * notifyAll   是唤醒所有正在等待该对象锁的线程.
  61. *
  62. * 应该优先使用notifyAll()方法, 因为唤醒所有线程比唤醒一个线程更容易让jvm找到最适合被唤醒的线程.
  63. * 对于上述方法,只有在当前线程中才能使用,否则报运行时错误java.lang.IllegalMonitorStateException: current thread not owner.
  64. * 从实现角度来分析:
  65. * 在线程调用wait()方法时,需要把它放到一个同步段里,否则将会出现"java.lang.IllegalMonitorStateException: current thread not owner"的异常。
  66. *
  67. * */
  68. }
  1. package edu.hust.test;
  2. public class ThreadWait2 implements Runnable {
  3. private Object monitor1 = new Object();
  4. private Object monitor2 = new Object();
  5. public void run() {
  6. synchronized (monitor1) {
  7. System.out.println("monitor1被锁住了");
  8. synchronized (monitor2) {
  9. System.out.println("monitor2被锁住了");
  10. try {
  11. System.out.println("monitor2进入wait()状态");
  12. monitor2.wait();
  13. } catch (InterruptedException e) {
  14. System.out.println("谁把我吵醒了.....");
  15. }
  16. }
  17. }
  18. }
  19. public void getMonitor() throws InterruptedException {
  20. Thread.sleep(3 * 1000); //让main Thread延迟3秒执行, 使myThread获得足够时间进行线程初始化
  21. synchronized (monitor2) {
  22. System.out.println("我取得了monitor2");
  23. }
  24. synchronized (monitor1) {
  25. System.out.println("我取得了monitor1");
  26. }
  27. }
  28. public static void main(String[] args) {
  29. ThreadWait2 threadWait2 = new ThreadWait2();
  30. Thread myThread = new Thread(threadWait2);
  31. myThread.start();
  32. try {
  33. threadWait2.getMonitor();
  34. } catch (InterruptedException e) {
  35. System.out.println("谁把我吵醒了.....");
  36. }
  37. }
  38. /*
  39. * 因为wait()方法没有被notify(), 所以程序不会自动结束. 但运行结果不会改变了:
  40. * monitor1被锁住了
  41. * monitor2被锁住了
  42. * monitor2进入wait()状态
  43. * 我取得了monitor2
  44. *
  45. * 分析:System.out.println("我取得了monitor1")这句话永远不会得到执行, 因为wait()被调用时只释放了monitor2的锁, 并没有释放monitor1的锁.
  46. * */
  47. }

        2. yield()
        让当前运行Thread放弃其所占用的cpu时间片,以便让其他Thread运行。用yield()方法的目的是让Thread能适当地轮转。但是,并不能保证达到此效果!因为,即使当前Thread放弃时间片,可是还有可能再次被JVM选中!也就是连任。

        3. join()

  1. package edu.hust.test;
  2. public class ThreadJoin {
  3. public void run() {
  4. System.out.println("普通打印语句1");
  5. System.out.println("普通打印语句2");
  6. }
  7. public static void main(String[] args) throws InterruptedException {
  8. Thread myThread = new Thread() {
  9. public void run() {
  10. try {
  11. Thread.sleep(1000);
  12. } catch (InterruptedException e) {
  13. System.err.println("谁把我吵醒了.....");
  14. }
  15. System.out.println("线程:" + Thread.currentThread().getName() + " 启动了");
  16. }
  17. };
  18. myThread.start();
  19. myThread.join();
  20. new ThreadSeq().run();
  21. }
  22. /*
  23. * 没有t.join(), 运行结果为:
  24. * 普通打印语句1
  25. * 普通打印语句2
  26. * 线程:Thread-0 启动了
  27. *
  28. * 加入t.join(), 运行结果为:
  29. * 线程:Thread-0 启动了
  30. * 普通打印语句1
  31. * 普通打印语句2
  32. *
  33. * join():让当前Thread加入到myThread线程的尾部,意味着myThread线程运行结束之前,当前Thread不会运行。
  34. * */
  35. }
时间: 2024-10-11 03:32:50

thread相关http://blog.csdn.net/forwayfarer/article/details/3455130的相关文章

推荐一些C#相关的网站、资源和书籍 (转载自http://blog.csdn.net/chinacsharper/article/details/17514923)

一.网站 1.http://msdn.microsoft.com/zh-CN/ 微软的官方网站,C#程序员必去的地方.那里有API开发文档,还有各种代码.资源下载. 2.http://social.msdn.microsoft.com/Forums/zh-CN/home 微软msdn论坛.定位于微软技术的传播和技术问题的解决,是学习微软技术的好去处. 3.http://www.codeproject.com/ 国外著名的社区网站,面向世界的程序员.有很多不错的程序都可以从那里下载到. 4.htt

http://blog.csdn.net/LANGXINLEN/article/details/50421988

GitHub上史上最全的Android开源项目分类汇总 今天在看博客的时候,无意中发现了 @Trinea在GitHub上的一个项目 Android开源项目分类汇总, 由于类容太多了,我没有一个个完整地看完,但是里面介绍的开源项目都非常有参考价值,包括很炫的界面特效设计.个性化控件.工具库.优秀的Android 开源项目.开发测试工具.优秀个人和团体等.可以这样说,每一位Andorid开发人员都能从中找到一个或多个适用自己项目的解决方案,消化吸收并加以利 用,可以为自己的APP增色不少.文章最后还

转:Java面试题集(51-70) http://blog.csdn.net/jackfrued/article/details/17403101

Java面试题集(51-70) Java程序员面试题集(51-70) http://blog.csdn.net/jackfrued/article/details/17403101 摘要:这一部分主要讲解了异常.多线程.容器和I/O的相关面试题.首先,异常机制提供了一种在不打乱原有业务逻辑的前提下,把程序在运行时可能出现的状况处理掉的优雅的解决方案,同时也是面向对象的解决方案.而Java的线程模型是建立在共享的.默认的可见的可变状态以及抢占式线程调度两个概念之上的.Java内置了对多线程编程的支

Cassandra研究报告-http://blog.csdn.net/zyz511919766/article/details/38683219/

转自http://blog.csdn.net/zyz511919766/article/details/38683219/ 1基本安装 1.1在基于RHEL的系统中安装Cassandra 1.1.1必要条件 Ø  YUM包管理器 Ø  Root或sudo权限 Ø  JRE6或者JRE7 Ø  JNA(Java native Access)(生产环境需要) 1.1.2步骤 Ø  安装配置JRE(略) Ø  添加软件包仓库到YUM的软件库 将以下内容添加进/etc/yum.repos.d/datas

Win32消息循环机制等【转载】http://blog.csdn.net/u013777351/article/details/49522219

Dos的过程驱动与Windows的事件驱动 在讲本程序的消息循环之前,我想先谈一下Dos与Windows驱动机制的区别: DOS程序主要使用顺序的,过程驱动的程序设计方法.顺序的,过程驱动的程序有一个明显的开始,明显的过程及一个明显的结束,因此程序能直接控制程序事件或过程的顺序.虽然在顺序的过程驱动的程序中也有很多处理异常的方法,但这样的异常处理也仍然是顺序的,过程驱动的结构. 而Windows的驱动方式是事件驱动,就是不由事件的顺序来控制,而是由事件的发生来控制,所有的事件是无序的,所为一个程

中文录入问题 转载自:http://blog.csdn.net/ichsonx/article/details/8625925

2.1中文录入问题 默认安装的msysgit的shell环境中无法输入中文,为了能在shell界面输入中文,需要修改配置文件/etc/inputrc,增加或修改相关配置如下: #disable/enable 8bit input set meta-flag on set input-meta on set output-meta on set convert-meta off 关闭bash再重启就可以输入中文了. 2.2分页器中文输出问题 对于/etc/inputrc正确配置之后能正确输入中文了

Windows下QT4.8.4编译环境的搭建(转载http://blog.csdn.net/bestgonghuibin/article/details/38933141)

开始使用QT了,所以第一步就是把环境搭起来,这里小记一下,以免以后忘记. 1. 下载安装文件 要使用QT功能,那么必须要下载QT的源码,还必须要一个是用QT的编译环境,可以是VS2010,也可以是专用于QT编程的QT Creator.本人选择QT Creator,所以也必须要下载QT Creator. 根据网上大部分教程及自己买的书籍获取的信息,在选择版本的时候,QT 源码选择4.8.4,而QT Creator选择2.8.0(QT5.0以后许多原有的文件路径改变). 选择好版本之后,可以上QT的

ABAP面试经历【转http://blog.csdn.net/tsj19881202/article/details/8792742】

本周三面试了一次HP的globe部门,整个过程自己感觉特别糟糕.总结了一下经验, 1.不能把自己平时做的东西,很好的用语言描述出来 2.技术点其实都会,但是不了解对方问题的意思,所以没能很好的回答对方的问题.比如问对方dialog有几个事件,我只记得有pai,pbo.其实f1和f4事件也是.但是我没有意识到.诸如此类的问题有很多. 3. 简历上一定要真实的经验.比如我简历上写了逻辑数据库知识,但是这个跟我理解的是有差别的. 以下是我面试的一些题目.只做参考 开始,就是英文的自我介绍,大致讲一下自

装载 - POJ分类很好很有层次感 from http://blog.csdn.net/zzycsx/article/details/49103451

from http://blog.csdn.net/zzycsx/article/details/49103451 OJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094)初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.