读书人

Java基础-第十二天 多线程

发布时间: 2013-02-25 10:23:36 作者: rapoo

Java基础---第十二天 多线程

一、线程间的通信

三、线程间通信-等待唤醒机制
1、wait(),notify(),notifyAll(),都使用在同步中,因为要对持有监视器(锁)的线程操作。所以要使用在同步中,因为只有同步才具有锁。
2、为什么这些操作线程的方法要定义Object类中呢?因为这些方法在操作同步中,线程,都必须要表示它们所操作线程只有的锁,只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒,不可以对不同锁中的线程进行唤醒。也就是说,等待和唤醒必须是同一个锁。
3、而锁可以是任意对象,所以可以被任意对象调用的方法定义Object类中。
[java] view plaincopy
  1. /*
  2. 线程间通讯:
  3. 其实就是多个线程在操作同一个资源,
  4. 但是操作的动作不同。
  5. */
  6. import java.lang.*;
  7. class Res{
  8. String name;
  9. String sex;
  10. boolean flag = false;
  11. }
  12. class Input implements Runnable{
  13. private Res r;
  14. Input(Res r){
  15. this.r = r;
  16. }
  17. public void run(){
  18. int x = 0;
  19. while(true){
  20. synchronized(r){
  21. if(r.flag){
  22. try{ r.wait();}catch(Exception e){}
  23. }
  24. if(x==0){
  25. r.name = "mike";
  26. r.sex = "man";
  27. }else{
  28. r.name = "丽丽";
  29. r.sex = "女女女女女";
  30. }
  31. x = (x+1)%2;
  32. r.flag = true;
  33. r.notify();
  34. }
  35. }
  36. }
  37. }
  38. class Output implements Runnable{
  39. private Res r;
  40. Output(Res r){
  41. this.r = r;
  42. }
  43. public void run(){
  44. while(true){
  45. synchronized(r){
  46. if(!r.flag){
  47. try{ r.wait();}catch(Exception e){}
  48. }
  49. System.out.println(r.name+" "+r.sex);
  50. r.flag = false;
  51. r.notify();
  52. }
  53. }
  54. }
  55. }
  56. public class Demo{
  57. public static void main(String args[]){
  58. Res r = new Res();
  59. Input in = new Input(r);
  60. Output out = new Output(r);
  61. Thread t1 = new Thread(in);
  62. Thread t2 = new Thread(out);
  63. t1.start();
  64. t2.start();
  65. }
  66. }


四、线程间通信-代码优化
[java] view plaincopy
  1. class Res{
  2. private String name;
  3. private String sex;
  4. private boolean flag = false;
  5. public synchronized void set(String name,String sex){
  6. if(this.flag){
  7. try{ this.wait();}catch(Exception e){}
  8. }
  9. this.name = name;
  10. this.sex = sex;
  11. this.flag = true;
  12. this.notify();
  13. }
  14. public synchronized void out(){
  15. if(!this.flag){
  16. try{ this.wait();}catch(Exception e){}
  17. }
  18. System.out.println(this.name+" "+this.sex);
  19. this.flag = false;
  20. this.notify();
  21. }
  22. }
  23. class Input implements Runnable{
  24. private Res r;
  25. Input(Res r){
  26. this.r = r;
  27. }
  28. public void run(){
  29. int x = 0;
  30. while(true){
  31. if(x==0){
  32. r.set("mike","man");
  33. }else{
  34. r.set("丽丽","女女女女女");
  35. }
  36. x = (x+1)%2;
  37. }
  38. }
  39. }
  40. class Output implements Runnable{
  41. private Res r;
  42. Output(Res r){
  43. this.r = r;
  44. }
  45. public void run(){
  46. while(true){
  47. r.out();
  48. }
  49. }
  50. }
  51. public class Demo{
  52. public static void main(String args[]){
  53. Res r = new Res();
  54. new Thread(new Input(r)).start();
  55. new Thread(new Output(r)).start();
  56. }
  57. }


五、线程间通信-生产者消费者
[java] view plaincopy
  1. class Demo{
  2. public static void main(String args[]){
  3. Resource r = new Resource();
  4. Producer pro = new Producer(r);
  5. Consumer con = new Consumer(r);
  6. Thread t1 = new Thread(pro);
  7. Thread t3 = new Thread(pro);
  8. Thread t2 = new Thread(con);
  9. Thread t4 = new Thread(con);
  10. t1.start();
  11. t2.start();
  12. t3.start();
  13. t4.start();
  14. }
  15. }
  16. class Resource{
  17. private String name;
  18. private int count = 1;
  19. private boolean flag = false;
  20. public synchronized void set(String name){
  21. while(flag){
  22. try{
  23. this.wait();
  24. }catch(Exception e){
  25. }
  26. }
  27. this.name = name+"--"+count++;
  28. System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
  29. flag = true;
  30. this.notifyAll();
  31. }
  32. public synchronized void out(){
  33. while(!flag){
  34. try{
  35. this.wait();
  36. }catch(Exception e){
  37. }
  38. }
  39. System.out.println(Thread.currentThread().getName()+"...消费者..........."+this.name);
  40. flag = false;
  41. this.notifyAll();
  42. }
  43. }
  44. class Producer implements Runnable{
  45. private Resource res;
  46. Producer(Resource res){
  47. this.res = res;
  48. }
  49. public void run(){
  50. while(true){
  51. res.set("+商品+");
  52. }
  53. }
  54. }
  55. class Consumer implements Runnable{
  56. private Resource res;
  57. Consumer(Resource res){
  58. this.res = res;
  59. }
  60. public void run(){
  61. while(true){
  62. res.out();
  63. }
  64. }
  65. }


六、线程间通信-生产者消费者JDK5.0升级版
1、jdk1.5中,提供了,许多县城升级解决方案,将同步 synchrozed 替换成 显示 Lock 操作
将 object 中的 wait ,notify,notifyAll,替换成了condition 对象。
该对象可以 Lock锁,进行获取
2、该实例中,实现了,本方置换型对方的操作。
[java] view plaincopy
  1. import java.util.concurrent.locks.*;
  2. class Demo{
  3. public static void main(String args[]){
  4. Resource r = new Resource();
  5. Producer pro = new Producer(r);
  6. Consumer con = new Consumer(r);
  7. Thread t1 = new Thread(pro);
  8. Thread t3 = new Thread(pro);
  9. Thread t2 = new Thread(con);
  10. Thread t4 = new Thread(con);
  11. t1.start();
  12. t2.start();
  13. t3.start();
  14. t4.start();
  15. }
  16. }
  17. class Resource{
  18. private String name;
  19. private int count = 1;
  20. private boolean flag = false;
  21. private Lock lock = new ReentrantLock();
  22. private Condition condition_pro = lock.newCondition();
  23. private Condition condition_con = lock.newCondition();
  24. public void set(String name) throws InterruptedException{
  25. lock.lock();
  26. try{
  27. while(flag){
  28. condition_pro.await();
  29. }
  30. this.name = name+"--"+count++;
  31. System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
  32. flag = true;
  33. condition_con.signal();
  34. }finally{
  35. lock.unlock();
  36. }
  37. }
  38. public void out() throws InterruptedException{
  39. lock.lock();
  40. try{
  41. while(!flag){
  42. condition_con.await();
  43. }
  44. System.out.println(Thread.currentThread().getName()+"...消费者..........."+this.name);
  45. flag = false;
  46. condition_pro.signal();
  47. }finally{
  48. lock.unlock();
  49. }
  50. }
  51. }
  52. class Producer implements Runnable{
  53. private Resource res;
  54. Producer(Resource res){
  55. this.res = res;
  56. }
  57. public void run(){
  58. while(true){
  59. try{
  60. res.set("+商品+");
  61. }catch(InterruptedException e){
  62. }
  63. }
  64. }
  65. }
  66. class Consumer implements Runnable{
  67. private Resource res;
  68. Consumer(Resource res){
  69. this.res = res;
  70. }
  71. public void run(){
  72. while(true){
  73. try{
  74. res.out();
  75. }catch(InterruptedException e){
  76. }
  77. }
  78. }
  79. }


七、停止线程
stop方法已经过时。
如何停止线程?
只有一种,run()方法结束
开启多线程运行,运行代码通常是循环结构。
只要控制住循环,就可以让run方法结束,也就是线程结束

当线程处于冻结状态,就不会读取到标记,那么线程就不会结束
当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除。
强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束
Thread类提供该方法, interrupt();
[java] view plaincopy
  1. class Demo{
  2. public static void main(String args[]){
  3. StopThread st = new StopThread();
  4. Thread t1 = new Thread(st);
  5. Thread t2 = new Thread(st);
  6. t1.start();
  7. t2.start();
  8. int num = 0;
  9. while(true){
  10. if(num++ == 60){
  11. st.changeFlag();
  12. t1.interrupt();
  13. t2.interrupt();
  14. break;
  15. }
  16. System.out.println(Thread.currentThread().getName()+num);
  17. }
  18. }
  19. }
  20. class StopThread implements Runnable{
  21. private boolean flag = true;
  22. public void run(){
  23. while(flag){
  24. System.out.println(Thread.currentThread().getName()+"....run");
  25. }
  26. }
  27. public void changeFlag(){
  28. flag = false;
  29. }
  30. }


八、守护线程
对象.setDemo(true) 如果主线程结束,则这个线程自动结束
九、Join方法
抢夺主线程行权,注意,只抢夺主线程
临时加入线程
当a线程执行到了b线程的 .join() 方法时,a就会等待,等b线程都执行完,a才会执行
[java] view plaincopy
  1. class Demo{
  2. public static void main(String args[]) throws Exception{
  3. StopThread st = new StopThread();
  4. Thread t1 = new Thread(st);
  5. Thread t2 = new Thread(st);
  6. t1.start();
  7. t1.join();
  8. t2.start();
  9. t2.join();
  10. for(int x=0;x<70;x++){
  11. System.out.println(Thread.currentThread().getName()+" "+x);
  12. }
  13. System.out.println("over");
  14. }
  15. }
  16. class StopThread implements Runnable{
  17. public void run(){
  18. for(int x=0;x<70;x++){
  19. System.out.println(Thread.currentThread().getName()+" "+x);
  20. }
  21. }
  22. }


10、Byield方法 礼让

setPriority 设置优先级

读书人网 >编程

热点推荐