码迷,mamicode.com
首页 > 编程语言 > 详细

Java多线程及JDK5线程工具类总结

时间:2015-07-07 00:42:32      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:

 

内容摘抄来自:传智播客 张孝祥 老师的《Java高新技术》视频,   并加入了个人总结和理解。
虽然我没有参加过任何培训班,但我很大一部分知识都来自于传智播客的网络分享视频。
十分真挚的感谢张老师的公开视频。
 
 
1.传统线程技术的回顾
 1 import org.junit.Test;
 2 /**
 3  * 传统线程回顾
 4  * 多线程不一定会提高运行效率,和CPU设计和架构有关。
 5  * 多线程下载是抢了服务器的资源,并不是自身的机器加快。
 6  * @author LiTaiQing
 7  */
 8 public class TraditionThread {
 9     /**
10      * 两种传统线程的创建方式
11      */
12     @Test
13     public void test1(){
14         //方式一
15         Thread thread = new Thread(){
16             /**
17              * 从Thread.class源代码中发现,run方法在默认情况下是执行默认target.run();
18              *  @Override
19                 public void run() {
20                     if (target != null) {
21                         target.run();
22                     }
23                 }
24                 
25                 private Runnable target;
26              */
27             @Override
28             public void run() {
29                 while(true){
30                     System.out.println(Thread.currentThread().getName());
31                     //不要使用this,因为在Runnable创建线程的方式中this是无效的
32                     //System.out.println(this.getName());
33                 }
34             }
35         };
36         thread.start();
37         /**
38          * 方式二
39          * 使用Runnable更好,更加符合面向对象程序设计的思想,程序结构的耦合性更低,将任务和宿主分离
40          */
41         Thread thread2 = new Thread(new Runnable(){
42             @Override
43             public void run() {
44                 while(true){
45                     System.out.println(Thread.currentThread().getName());
46                     //报错
47                     //System.out.println(this.getName());
48                 }
49             }
50         });
51         thread2.start();
52         //-------------------------------------
53         /**
54          * 考虑回运行哪一块代码?
55          */
56         new Thread(new Runnable(){
57             @Override
58             public void run() {
59                 while(true){
60                     try {
61                         Thread.sleep(500);
62                     } catch (InterruptedException e) {
63                         e.printStackTrace();
64                     }
65                     System.out.println("Runable:"+Thread.currentThread().getName());
66                 }
67             }
68         }){
69             /**
70              *     会运行此代码块,子类覆盖了父类的方法 ,那么就先运行子类,否则就去找父类    
71              */
72             @Override
73             public void run() {
74                 while(true){
75                     try {
76                         Thread.sleep(500);
77                     } catch (InterruptedException e) {
78                         e.printStackTrace();
79                     }
80                     System.out.println("Run:"+Thread.currentThread().getName());
81                 }
82             }
83         }.start();
84     }
85 }
2.传统定时器技术回顾   -   Timer类   TimerTask

java.util 
类 Timer

java.lang.Object
  java.util.Timer
方法摘要
void cancel() 
          终止此计时器,丢弃所有当前已安排的任务。
 int purge() 
          从此计时器的任务队列中移除所有已取消的任务。
void schedule(TimerTask task, Date time) 
          安排在指定的时间执行指定的任务。
void schedule(TimerTask task, Date firstTime, long period) 
          安排指定的任务在指定的时间开始进行重复的固定延迟执行
void schedule(TimerTask task, long delay) 
          安排在指定延迟后执行指定的任务。
void schedule(TimerTask task, long delay, long period) 
          安排指定的任务从指定的延迟后开始进行重复的固定延迟执行
void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) 
          安排指定的任务在指定的时间开始进行重复的固定速率执行
void scheduleAtFixedRate(TimerTask task, long delay, long period) 
          安排指定的任务在指定的延迟后开始进行重复的固定速率执行
 
 
 1 import java.util.Date;
 2 import java.util.Timer;
 3 import java.util.TimerTask;
 4 import org.junit.Test;
 5 /**
 6  * 传统定时器
 7  * 工具 quartz 可以完成在周几执行任务的需求
 8  * @author LiTaiQing
 9  */
10 public class TraditionalTimerTest {
11     /**
12      * 传统定时器的使用实例
13      */
14     @Test
15     public void test1(){
16         /*
17          * schedule 调度
18          * Timer是定时器
19          * TimerTask是定时器的任务
20          */
21         new Timer().schedule(new TimerTask(){
22             @Override
23             public void run() {
24                 System.out.println("bombing!");
25             }
26         }, 10000,3000);//第一次执行是10秒之后,以后每隔3秒执行一次
27         printSeconds();
28     }
29     
30     /**
31      * 实现刚开始2秒执行,之后4秒执行一次
32      *         代码思想从每次2秒执行一次改到目标结果
33      */
34     //通过一个标记,判断当前任务应该多少秒后执行
35     private static int count = 0;
36     @Test
37     public void test2(){
38         /**
39          * 内部类内部不能出现静态变量。
40          */
41         class MyTimerTask extends TimerTask{
42             @Override
43             public void run() {
44                 count = (count + 1)%2;
45                 System.out.println("bombing!");
46                 new Timer().schedule(
47                     /*new TimerTask(){
48                         @Override
49                         public void run() {
50                             System.out.println("bombing!");
51                         }
52                     }*/
53                 new MyTimerTask(), 2000+2000*count);
54             }    
55         }
56         new Timer().schedule(new MyTimerTask(),2000);
57         printSeconds();
58     }
59     
60     /**
61      * “实现任务刚开始2秒执行,之后4秒执行一次”的另一种方法
62      */
63     @Test
64     public void test3(){
65         new Timer().schedule(new MyTimerTask2(), 2000);
66         printSeconds();
67     }
68     class MyTimerTask1 extends TimerTask{
69         @Override
70         public void run() {
71             System.out.println("bombing!");
72             new Timer().schedule(new MyTimerTask2(), 2000);
73         }    
74     }
75     class MyTimerTask2 extends TimerTask{
76         @Override
77         public void run() {
78             System.out.println("bombing!");
79             new Timer().schedule(new MyTimerTask1(), 4000);
80         }    
81     }
82     
83     private void printSeconds(){
84         while(true){
85             System.out.println(new Date().getSeconds());
86             try {
87                 Thread.sleep(1000);
88             } catch (InterruptedException e) {
89                 e.printStackTrace();
90             }
91         }
92     }
93 }
3.传统线程互斥技术
    线程安全问题可以用银行转账来解释
 1 /**
 2  * 传统的线程互斥技术
 3  * @author LiTaiQing
 4  */
 5 public class TraditionalThreadSynchronized {
 6     
 7     public static void main(String[] args){
 8         new TraditionalThreadSynchronized().init();
 9     }
10     
11     private void init(){
12         /**
13          * 内部类访问局部变量,局部变量要加final
14          *         若此代码放在main中会报错,因为静态代码块不能访问内部类
15          */
16         final Outputer outputer = new Outputer();
17         new Thread(new Runnable(){
18             @Override
19             public void run() {
20                 while(true){
21                     try {
22                         Thread.sleep(1000);
23                     } catch (InterruptedException e) {
24                         e.printStackTrace();
25                     }
26                     outputer.output("zhangxiaoxiang");
27                 }
28             }
29         }).start();
30         new Thread(new Runnable(){
31             @Override
32             public void run() {
33                 while(true){
34                     try {
35                         Thread.sleep(1000);
36                     } catch (InterruptedException e) {
37                         e.printStackTrace();
38                     }
39                     outputer.output("lihuoming");
40                 }
41             }
42         }).start();
43     }
44     
45     static class Outputer{
46         public void output(String name){
47             int len = name.length();
48             /*
49              * 锁用任意一个对象都行,但只有同一个对象才具有互斥性
50              * 1.每个类的字节码文件只有一份,可以用来做互斥锁
51              * 2.用this也行
52              * 此处也可以在方法上架synchroized,
53              * 但从多线程效率角度来看,合理细化同步块粒度能提高执行效率,
54              * 所以此处在内部代码中加synchroized比较好
55              */
56             synchronized(Outputer.class){
57                 for(int i = 0; i < len ; i++){
58                     System.out.print(name.charAt(i));
59                 }
60                 System.out.println();
61             }
62         }
63         /**
64          * output2方法不会同步,因为方法上加synchronized相当于加this锁
65          * 但又是静态方法,所以this会失效,会出现问题。
66          * @param name
67          */
68         public static synchronized void output2(String name){
69             int len = name.length();
70             synchronized(Outputer.class){
71                 for(int i = 0; i < len ; i++){
72                     System.out.print(name.charAt(i));
73                 }
74                 System.out.println();
75             }
76         }
77     }
78 }

4.传统线程同步通信技

 1 /**
 2  * 传统线程同步通信技术
 3  * 
 4  * *******************************************
 5  * 经验:
 6  *       要用到共同数据(包括共同锁)或共同算法的若干个方法应该
 7  * 归在用一个类身上,这种设计正好体现了高内聚和程序的健壮性。
 8  * 
 9  * *******************************************
10  *  
11  * @author LiTaiQing
12  */
13 public class TraditionalThreadCommunication {
14 
15     /**************************************************
16      * 调试小技巧
17      * 如果由于Console的输出太多而造成面板显示的数据不完整
18      * 可设置运行前参数设置
19      * 右键->Run As->Run Configuractions->Common->File
20      * 选择保存的路径即可
21      * 
22      **************************************************
23      */
24     
25     
26     /**
27      * 面试题 
28      * ·子线程循环10次,接着主线程循环100,接着又回到子线程循环10次, 
29      * ·接着再回到主线程又循环100,如此循环50次,请写出程序
30      */
31     public static void main(String[] args){
32         
33         final Business business = new Business();
34         new Thread(new Runnable(){
35             @Override
36             public void run() {
37                 for(int i = 1; i <= 50; i++){
38                     business.sub(i);
39                 }
40             }
41         }).start();
42         for(int i = 1; i <= 50; i++){
43             business.main(i);
44         }
45     }
46 
47 }
48 
49 class Business{
50     private boolean bShouldSub = true;
51     public synchronized void sub(int i){
52         /**
53          * 此处将if改为while,增强代码健壮性。
54          * 防止伪唤醒!
55          */
56         while(!bShouldSub){
57             try {
58                 this.wait();
59             } catch (InterruptedException e) {
60                 e.printStackTrace();
61             }
62         }
63         for(int j = 1; j <= 10; j++){
64             System.out.println("sub thread sequece of " + j + ",loop of " +i);
65         }
66         bShouldSub = false;
67         this.notify();
68     }
69     public synchronized void main(int i){
70         while(bShouldSub){
71             try {
72                 this.wait();
73             } catch (InterruptedException e) {
74                 e.printStackTrace();
75             }
76         }
77         for(int j = 1; j <= 100; j++){
78             System.out.println("main thread sequece of " + j + ",loop of " +i);
79         }
80         bShouldSub = true;
81         this.notify();
82     }
83 }

 

5.线程范围内共享变量的概念与作用

 1 import java.util.HashMap;
 2 import java.util.Map;
 3 import java.util.Random;
 4 
 5 /*******************************
 6  * 模拟ThrealLocal的实现
 7  * 用处:
 8  *  用在数据库操作中俄beginTransaction -> commit
 9  *  在Hibernate中也是使用它来保证在多线程下Session自己不冲突。
10  *     OpenSessionInView模式
11  *        spring的OpenSessionInView也是使用ThreadLocal来实现, OpenSessionInViewFilter过滤器
12  *        当请求到底是打开一个session,请求结束时关闭。
13  *        缺陷就是如果客户端的网速慢,会导致数据库的链接一直被占用。
14  *    扩展:OpenSessionInView模式用AOP替代
15  * *****************************
16  * @author LiTaiQing
17  */
18 public class ThreadScopeShareData {
19     private static Map<Thread,Integer> threadData = new HashMap<Thread,Integer>();
20     public static void main(String[] args){
21         for(int i = 0; i < 10 ; i++){
22             new Thread(new Runnable(){
23                 @Override
24                 public void run() {
25                     int data = new Random().nextInt();
26                     System.out.println(Thread.currentThread().getName() + " get put data :" + data);
27                     threadData.put(Thread.currentThread(), data);
28                     new A().get();
29                     new B().get();
30                 }
31             }).start();
32         }
33     }
34     static class A{
35         public void get(){
36             int data = threadData.get(Thread.currentThread());
37             System.out.println("A from" + Thread.currentThread().getName() + " get put data :" + data);
38         }
39     }
40     static class B{
41         public void get(){
42             int data = threadData.get(Thread.currentThread());
43             System.out.println("B from" + Thread.currentThread().getName() + " get put data :" + data);
44         }
45     }

 

 

 

 

Java多线程及JDK5线程工具类总结

标签:

原文地址:http://www.cnblogs.com/litaiqing/p/4625718.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!