线程学习总结及例子


  1. package com.hanchao.test; 
  2. /** 
  3.  * 线程的创建方法一:继承java.lang.Thread类 
  4.  * @author hanlw 
  5.  * 2012 -07 -06 
  6.  */ 
  7. public class Thread1 extends Thread{ 
  8.  
  9.     @Override 
  10.     public void run() { 
  11.         //重写了Thread类的run()方法,该方法中是线程该做的事! 
  12.          
  13.         System.out.println("线程的创建方法一:继承java.lang.Thread类;要重写run()方法。"); 
  14.          
  15.     } 

  1. package com.hanchao.test; 
  2. /** 
  3.  * 线程的创建方法二:实现java.lang.Runnable接口 
  4.  * @author hanlw 
  5.  * 2012 -07 -06 
  6.  */ 
  7. public class Thread2 implements Runnable{ 
  8.  
  9.     public void run() { 
  10.         //实现Runnable接口的run()方法,该方法中写的是线程应该做的事! 
  11.         System.out.println("线程的创建方法二:实现java.lang.Runnable接口,并实现其run()方法"); 
  12.     } 
  13.      
  14.      

 


  1. package com.hanchao.test; 
  2. /** 
  3.  * 守护线程的测试类 
  4.  * @author hanlw 
  5.  * 2012- 07 -06 
  6.  */ 
  7. public class Thread3 extends Thread{ 
  8.  
  9.     @Override 
  10.     public void run() { 
  11.          
  12.         while(true) { 
  13.              
  14.             System.out.println("非守护线程"); 
  15.              
  16.             //线程睡上1000ms= 1s 
  17.             try { 
  18.                 this.sleep(1000); 
  19.             } catch (InterruptedException e) { 
  20.                 e.printStackTrace(); 
  21.             } 
  22.         } 
  23.     } 

 


  1. package com.hanchao.test; 
  2. /** 
  3.  * 线程同步问题的测试类 
  4.  * @author hanlw 
  5.  * 2012 -07 -06 
  6.  */ 
  7. public class Account { 
  8.  
  9.     private float money = 2000f; 
  10.      
  11.     public void getMoney(String name,float money) { 
  12.         if(money > this.money) { 
  13.             System.out.println("余额不足,当前余额为:"+this.money); 
  14.         } else { 
  15.             this.money -= money; 
  16.             System.out.println(name+"取款成功,当前余额为:"+this.money); 
  17.         } 
  18.     } 

 


  1. package com.hanchao.test; 
  2. /** 
  3.  * 线程同步问题的测试类 
  4.  * @author hanlw 
  5.  * 2012 - 07 - 06 
  6.  */ 
  7. public class User extends Thread{ 
  8.  
  9.     private Account account; 
  10.     private String name; 
  11.     private float money; 
  12.      
  13.     /** 
  14.      * 构造方法 
  15.      * @param account 
  16.      * @param name 
  17.      * @param money 
  18.      */ 
  19.     public User(Account account,String name,float money) { 
  20.         this.account = account; 
  21.         this.name = name; 
  22.         this.money = money; 
  23.     } 
  24.      
  25.     @Override 
  26.     public void run() { 
  27.          
  28.         try { 
  29.             this.sleep(2000);//等待取款时间为2s 
  30.             account.getMoney(name, money); 
  31.         } catch (InterruptedException e) { 
  32.             e.printStackTrace(); 
  33.         } 
  34.     } 
  35.      

 


  1. package com.hanchao.test; 
  2. /** 
  3.  * 线程学习的测试类 
  4.  * @author hanlw 
  5.  * 
  6.  */ 
  7. public class Test_Six { 
  8.  
  9.     public static void main(String[] args) throws Exception { 
  10.          
  11.         /** 
  12.          * 线程的学习: 
  13.          *  
  14.          * 1.进程:同一时间片,单核只有一个进程运行。一个进程包括多个线程。 
  15.          *  
  16.          * 2.所谓的进程,本身不能执行,它只是一个资源的集合体,拥有地址空间,模块,内存。 
  17.          *  
  18.          *   线程是真正的执行单元,如果一个进程没有线程,那么就没有存在的意义,因为不可能执行。 
  19.          *    
  20.          * 3.线程的创建有两种方法: 
  21.          *  
  22.          *   ① 继承java.lang.Thread类,并重写run()方法。 
  23.          *   ② 实现java.lang.Runnable接口,并实现其run()方法。 
  24.          *    
  25.          */ 
  26.          
  27.         /** 
  28.          * 4.线程的启动(以前一直存在主线程main()方法) 
  29.          */ 
  30.         //①,继承java.lang.Thread类的线程的启动 
  31. /*      Thread1 t1 = new Thread1(); 
  32.         t1.start(); 
  33.          
  34.         //②实现java.lang.Runnable接口的线程的启动 
  35.         Thread t2 = new Thread(new Thread2()); 
  36.         t2.start(); 
  37. */       
  38.         /** 
  39.          * 5.注意事项: 
  40.          *  
  41.          * ①继承Thread类后,无法再继承其他的类,但是实现Runnable接口后,还可以继承其他的类 
  42.          *  
  43.          * ②实现Runnable接口,访问当前线程需要使用Thread.currentThread()方法 
  44.          * eg.Thread.currentThread().getName(); 
  45.          *    Thread.currentThread().getId(); 
  46.          *  
  47.          * ③继承Thread类,访问当前线程也可以使用this即可。 
  48.          *  eg. this.currentThread() 
  49.          *   
  50.          *   
  51.          *  6.线程的生命周期:注意如下 
  52.          *   
  53.          *  ①可以使用isAlive()方法判断线程是否死亡,该方法在线程处于就绪、运行、阻塞三种状态时返回true; 
  54.          *    处于新建及死亡状态时返回false; 
  55.          *     
  56.          *  ②线程一旦死亡,则不能再次调用start()方法,让其重新执行。 
  57.          *  (一个线程只能调用一次start()方法) 
  58.          *   
  59.          */ 
  60.          
  61.         /** 
  62.          * 7.join()线程: 
  63.          *   Thread提供了让一个线程等待另一个线程完成的方法:join()。当某个程序在执行过程中调用了其他 
  64.          *   线程的join()方法,则当前线程被阻塞,直到被join()方法加入的线程完成为止。例子如下: 
  65.          */ 
  66.         //join()线程的例子: 
  67.          
  68. /*      for (int i = 0; i < 20; i++) { 
  69.             System.out.println("当前线程为:"+Thread.currentThread().getName()+"\t"+i); 
  70.              
  71.             //当i为6时,我们加入Thread1线程 
  72.             if(i == 6) { 
  73.                 Thread1 t11 = new Thread1(); 
  74.                 t11.start(); 
  75.                 t11.join(); 
  76.             } 
  77.         } 
  78.          
  79. */       
  80.         /** 
  81.          * 8.守护线程: 
  82.          * 说明:除了特别设置外,我们创建的线程都是非守护线程。 
  83.          *     守护线程死亡了,守护线程也将死亡。 
  84.          *  
  85.          * 以前一直存在主线程main() 
  86.          */ 
  87.         //例子: 
  88. /*      Thread3 t3 = new Thread3(); 
  89.         t3.setDaemon(true);//设置守护线程。必须在start()前面啊!!! 
  90.         t3.start(); 
  91.          
  92.         for (int i = 0; i < 10; i++) { 
  93.             System.out.println(i); 
  94.         } 
  95. */       
  96.         /** 
  97.          * 9.线程的同步问题: 
  98.          *  
  99.          * ①:要使用多线程编程? 
  100.          *       多线程就象是人体一样,一直在并行的做许多工作,例如,人可以同时呼吸,血液循环,消化食物的。 
  101.          *    多线程可以将一个程序划分成多个任务,他们彼此独立的工作,以方便有效的使用处理器和用户的时 
  102.          *    间.这种比喻精辟,只要我们的机器资源够用,就要尽量提高程序的执行速度,这样能让用户感到舒服。 
  103.          *     
  104.          * ②: 同步就是说多个任务之间是有先后关系的,一个任务需要等待另一个任务执行完毕才能继续执行。 
  105.          *        异步就是说多个任务之间没有先后关系,不需要相互等待各做各的事。   
  106.          *  
  107.          * ③:当多个对象同时对同一对象的实例变量进行操作时,会引起线程同步的问题。 
  108.          * 如下面的取款问题:模拟两个用户同时开始取款。 
  109.          * 当我们不停的执行时,我们会发现,有时候是tom取款成功,有时候是jack取款成功,有时候二者都可以取款成功 
  110.          * 显然这是不对的!! 
  111.          *  
  112.          *   
  113.          *   线程同步问题的避免方法: 
  114.          * <1>.要避免线程同步的问题,首先要避免实现全局的实例变量。 
  115.          * <2>.使用同步方法  ,如 public synchronized void ... 
  116.          * <3>.使用同步代码块, synchronized (this) { 
  117.          *                      可能产生同步问题的程序 
  118.          *                 } 
  119.          * <4>.使用同步锁(JDK1.5以后才有的 
  120.          *  
  121.          * ④: 线程同步的方法: 
  122.          *  
  123.          *    wait():使一个线程处于等待状态,并且释放所持有的对象的lock。 
  124.          *  
  125.          *    sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法, 
  126.          *                       调用此方法要捕捉InterruptedException异常。 
  127.          *  
  128.          *    notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候, 
  129.          *                         并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程, 
  130.          *              而且不是按优先级。 
  131.          *  
  132.          *    AnotityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁, 
  133.          *                  而是让它们竞争。 
  134.          *     
  135.          *     
  136.          *     
  137.          */ 
  138.         //模拟取款 
  139.         Account account = new Account(); 
  140.         User  user1 = new User(account, "tom"1500);//tom取1500大洋 
  141.         User  user2 = new User(account, "jack"1500);//jack取1500大洋 
  142.          
  143.         user1.start(); 
  144.         user2.start(); 
  145.          
  146.     } 

1.同步方法:


  1. package com.hanchao.test; 
  2. /** 
  3.  * 线程同步问题的测试类 
  4.  * @author hanlw 
  5.  * 2012 -07 -06 
  6.  */ 
  7. public class Account { 
  8.  
  9.     private float money = 2000f; 
  10.      
  11.     public synchronized void getMoney(String name,float money) { 
  12.         if(money > this.money) { 
  13.             System.out.println("余额不足,当前余额为:"+this.money); 
  14.         } else { 
  15.             this.money -= money; 
  16.             System.out.println(name+"取款成功,当前余额为:"+this.money); 
  17.         } 
  18.     } 

2.同步代码块


  1. package com.hanchao.test; 
  2. /** 
  3.  * 线程同步问题的测试类 
  4.  * @author hanlw 
  5.  * 2012 -07 -06 
  6.  */ 
  7. public class Account { 
  8.  
  9.     private float money = 2000f; 
  10.      
  11.     public void getMoney(String name,float money) { 
  12.         synchronized (this) { 
  13.             if(money > this.money) { 
  14.                 System.out.println("余额不足,当前余额为:"+this.money); 
  15.             } else { 
  16.                 this.money -= money; 
  17.                 System.out.println(name+"取款成功,当前余额为:"+this.money); 
  18.             } 
  19.         } 
  20.     } 

3.同步锁


  1. package com.hanchao.test; 
  2.  
  3. import java.util.concurrent.locks.ReentrantLock; 
  4.  
  5. /** 
  6.  * 线程同步问题的测试类 
  7.  * @author hanlw 
  8.  * 2012 -07 -06 
  9.  */ 
  10. public class Account { 
  11.  
  12.     private float money = 2000f; 
  13.     private final ReentrantLock lock = new ReentrantLock(); 
  14.      
  15.     public void getMoney(String name,float money) { 
  16.             lock.lock();//枷锁 
  17.             try { 
  18.                 if(money > this.money) { 
  19.                     System.out.println("余额不足,当前余额为:"+this.money); 
  20.                 } else { 
  21.                     this.money -= money; 
  22.                     System.out.println(name+"取款成功,当前余额为:"+this.money); 
  23.                 } 
  24.             } catch (Exception e) { 
  25.                 e.printStackTrace(); 
  26.             } finally { 
  27.                 lock.unlock();//解锁 
  28.             } 
  29.              
  30.     } 

 

 

 

线程学习总结及例子

     本文转自韩立伟 51CTO博客,原文链接:http://blog.51cto.com/hanchaohan/923199,如需转载请自行联系原作者