多线程分享

    一、多线程相关关键字

    Runnable、Thread:线程的父类,区别就是使用Runnable接口不可以使用Thread的相关的特性,如sleep等;
    run:线程类中必须存在的方法;
    start:启动一个线程,经常被面试的人提到,我很郁闷;

    synchronized:同步锁,指定不同的对象,锁的内容不同,如一把锁可以锁门,也可以锁窗户;
    wait:先休息休息,好了的时候再叫我,但别忘了先锁门哦;
    notify:让一个等待的线程活动起来,效率高点;
    notifyAll:让所有等待的线程都起来抢东西了,但我更安全;
    sleep:先休息休息,一会儿自己醒来,除非你不让我休息了;
    interrupt:休息这以久还没有等到,不等了,但是不是中断这个线程;
    setDaemon:守护线程,请不要在乎我的存在,我是为主人服务的;
    join:等等,好了再继续;

    yield:不释放锁的等待,尽可能把优先级交给其它线程,不可以放到synchronized锁定中;
    ThreadLocal:多线程我也不怕共享资源。

    Volatile:参看 Java 理论与实践: 正确使用 Volatile 变量

    二、实例

    1、我是一个线程,展示一个简单的线程是怎么样练成的:

  1. public   class  IamThread  extends  Thread {  
  2.     public   void  run(){  
  3.         System.out.println("I am a thread" );  
  4.     }  
  5. }  
  6. 或者  
  7. public   class  IamThread  implements  Runnable {  
  8.     public   void  run(){  
  9.         System.out.println("I am a thread" );  
  10.     }  
  11. }  
  12. 启动线程:  
  13. new  Thread( new  IamThread()).start()  

    2、休息休息再说,这个是对sleep的简单使用,休息指定的时间后再工作,这里的时间设的长,是因为3要使用到它:

  1. public   class  IamThread  extends  Thread {  
  2.     public   void  run() {  
  3.         int  i =  0 ;  
  4.         while  ( true ) {  
  5.             try  {  
  6.                 sleep(1000000000 );  
  7.             } catch  (InterruptedException e) {  
  8.             }  
  9.             System.out.println(i++);  
  10.         }  
  11.     }  
  12. }  

    3、睡醒了吧,懒虫,不要一直让他沉睡,过2秒钟醒他一下,“工作”后,再继续睡,然后再过2秒钟再弄醒一下...如些循环,这里需要注意一下方法interrupt(),不要把这个理解为中断线程,理解为把当程线程唤醒更贴切:

  1. public   class  RunThread {  
  2.     public   static   void  main(String[] args) {  
  3.         Thread thread = new  Thread( new  IamThread());  
  4.         thread.start();  
  5.         while  ( true ) {  
  6.             try  {  
  7.                 Thread.sleep(2000 );  
  8.             } catch  (InterruptedException e) {  
  9.             }  
  10.             thread.interrupt();  
  11.         }  
  12.     }  
  13. }  

    4、饭好了叫我,对wait的使用示例,将线程放入到虚拟的wait set中,当对线程使用wait时,但是要想使用wait等待线程,需要注意两点,一是必须要获取锁定,如这里的synchroinzed关键字,二是必 须要有notify()或notifyAll()方法来叫醒,否则线程会永远醒不过来:

  1. public   class  WaitThread  extends  Thread {  
  2.     private   boolean  isReady =  false ;  
  3.     public   synchronized   void  eat(){  
  4.         if (!isReady){  
  5.             try  {  
  6.                 wait();  
  7.             } catch  (InterruptedException e) {}              
  8.         }  
  9.         System.out.println("I eat happy!" );  
  10.     }  
  11.     public   synchronized   void  cook(){  
  12.         isReady = true ;  
  13.         //notify();   
  14.         notifyAll();  
  15.     }  
  16. }  

    5、Join,全部好了再走,JOIN的使用情况是要获取到一个线程或者多个线程执行结果后,再继续执行下面的步骤,如果用采用JOIN,也许启动的线程 还没有执行完毕,JVM就退出了;既然JVM可以等到线程执行完后再继续下面的步骤,我们可否使用JOIN来做分布式运算,这个你自己想哦:

  1. public   class  JoinThread  extends  Thread {  
  2.     private   static   int  n =  0 ;  
  3.     public   void  run() {  
  4.         for  ( int  i =  0 ; i <  10 ; i++)  
  5.             try  {  
  6.                 addN();  
  7.                 //sleep(3); // 为了使运行结果更随机,延迟3毫秒   
  8.             } catch  (Exception e) {}  
  9.     }  
  10.     private   synchronized   void  addN() {n++;}  
  11.         public   static   void  main(String[] args)  throws  Exception {  
  12.         Thread threads[] = new  Thread[ 100 ];  
  13.         for  ( int  i =  0 ; i < threads.length; i++) {  
  14.             threads[i] = new  JoinThread();  
  15.         }  
  16.         for  ( int  i =  0 ; i < threads.length; i++) {  
  17.             threads[i].start();  
  18.         }  
  19.         // if (args.length > 0) {   
  20.         for  ( int  i =  0 ; i < threads.length; i++) {  
  21.             // 100个线程都执行完后继续   
  22.             threads[i].join();  
  23.         }  
  24.         // }   
  25.         System.out.println("n="  + JoinThread.n);  
  26.     }  
  27. }   

     注:以上的示例,并不是每次都会得到1000,这个我目前没有想明白是为什么,因为当上面执行到最后的输出的时候,启动的100个线程都已经执行完了,如果你有答案,请告诉我,我会非常感谢。

    6、守护线程,JVM不需要依赖于守护线程是否执行完毕来确定是否退出,他的优先级很低,如垃圾收集集,待其它的线程需要执行时,袒护线程就会等其它线程 执行,如果全部执行完了,虚拟机不会在意守护线程是否还有任务在执行,都会退出。简单的理解为守护线程为家仆,其它线程为主人,只需要看主人的脸色,而不 会在科家仆的脸色,主人完了,那家仆完不完已经不重要了:

  1. public   class  RunDeamonThread {  
  2.     public   static   void  main(String[] args){  
  3.         Thread doorKeeper = new  Thread( new  DoorKeeper());  
  4.         doorKeeper.setDaemon(true );  
  5.         doorKeeper.start();int  i= 0 ;          
  6.         while (i< 100 ){  
  7.             Thread thread = new  Thread( new  IamThread());  
  8.             thread.start();  
  9.             i++;  
  10.         }  
  11.     }  
  12. }  
  13. class  DoorKeeper  extends  Thread{  
  14.     public   void  run(){  
  15.         while ( true ){  
  16.             System.out.println("I am a door guander,don't care me!" );  
  17.         }  
  18.     }  
  19. }  

    7、ThreadLocal,用于在线程中传递变量

    只有四个方法:
    get() 返回此线程局部变量的当前线程副本中的值。
    initialValue() 返回此线程局部变量的当前线程的“初始值”。只在get或set时执行一次
    remove() 移除此线程局部变量当前线程的值。
    set(T value) 将此线程局部变量的当前线程副本中的值设置为指定值。

  1. public   class  ThreadGlobalTest {  
  2.     private   static  ThreadLocal<String> priviewStatus =   
  3.         new  ThreadLocal<String>();  
  4.     public   static  String getPriviewStatus() {  
  5.         return  priviewStatus.get();  
  6.     }  
  7.     public   static   void  setPriviewStatus(String status) {  
  8.         priviewStatus.set(status);  
  9.     }  
  10. }  

     8、yield,我一直等待,但是我也一直在工作,条件好了我就闪

 

  1. public   class  YieldTest {  
  2.     private   volatile   boolean  ready;  
  3.     //注意此方法不可以加synchronized,因为yield是一种不会释放锁的等待   
  4.     public   void  doSomething() {  
  5.         while  (!ready) {  
  6.             Thread.yield();  
  7.         }  
  8.     }  
  9.     public   synchronized   void  setReady() {  
  10.         ready = true ;  
  11.     }  
  12. }  
 

    三、一个巩固实例

    这个实例是别人发到JAVAEYE上面的,我看的蛮有意思的,就贴在这里,

  1. public   class  Test {  
  2.     public   static   void  main(String[] args) {  
  3.         MyClass1 myClass = new  MyClass1();  
  4.         new  MyThread(myClass).start();  
  5.         new  MyThread1(myClass).start();  
  6.     }  
  7. }  
  8. class  MyClass1 {  
  9.     public   synchronized   void  m1() {  
  10.         System.out.println("m1-1" );  
  11.         try  {  
  12.             this .wait();  // 暂停改当前线程,并且会释放锁   
  13.         } catch  (Exception e) {  
  14.             e.printStackTrace();  
  15.         }  
  16.         System.out.println("m1-2" );  
  17.         try  {  
  18.             Thread.sleep(1000 );  // m1和m2同时暂停1秒钟   
  19.             System.out.println("m1-3" );  
  20.         } catch  (InterruptedException e) {  
  21.             e.printStackTrace();  
  22.         }  
  23.         System.out.println("m1-4" );  
  24.         m2();  
  25.     }  
  26.     public   synchronized   void  m2() {  
  27.         System.out.println("m2-1" );  
  28.         this .notifyAll();  // 叫醒m1   
  29.         System.out.println("m2-2" );  
  30.         try  {  
  31.             Thread.sleep(1000 );  
  32.             System.out.println("m2-3" );  
  33.         } catch  (InterruptedException e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.         System.out.println("m2-4" );  
  37.         m1();  
  38.     }  
  39. }  
  40. class  MyThread  extends  Thread {  
  41.     private  MyClass1 myClass;  
  42.     public  MyThread(MyClass1 myClass){  
  43.         this .myClass = myClass;  
  44.     }  
  45.     @Override   
  46.     public   void  run() {  
  47.         myClass.m1();  
  48.     }  
  49. }  
  50. class  MyThread1  extends  Thread {  
  51.     private  MyClass1 myClass;  
  52.     public  MyThread1(MyClass1 myClass){  
  53.         this .myClass = myClass;  
  54.     }  
  55.     @Override   
  56.     public   void  run() {  
  57.         try  {  // 暂停10毫秒是为了让m1先执行wait   
  58.             Thread.sleep(10 );  
  59.         } catch  (InterruptedException e1) {  
  60.             e1.printStackTrace();  
  61.         }  
  62.         myClass.m2();  
  63.     }  
  64. }  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值