多线程<一>创建的五中方式

一,多线程创建方式一继承Thread类创建线程

假如你现在还在为自己的技术担忧,假如你现在想提升自己的工资,假如你想在职场上获得更多的话语权,假如你想顺利的度过35岁这个魔咒,假如你想体验BAT的工作环境,那么现在请我们一起开启提升技术之旅吧,详情请点击http://106.12.206.16:8080/qingruihappy/index.html

Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。例如:

 1 public class MyThread extends Thread {  
 2   public void run() {  
 3    System.out.println("MyThread.run()");  
 4   }  
 5 }  
 6  
 7 MyThread myThread1 = new MyThread();  
 8 MyThread myThread2 = new MyThread();  
 9 myThread1.start();  
10 myThread2.start();

这种方式主要的原理就是继承了tread类,当

我们来看一下源码当调用start方法的时候,就会调用start0的方法,而start0有一个native关键字,我们可以理解成当调用start0的时候才去调用了run的方法。

 1  public synchronized void start()
 2     {
 3         boolean flag;
 4         if(threadStatus != 0)
 5             throw new IllegalThreadStateException();
 6         group.add(this);
 7         flag = false;
 8         start0();
 9         flag = true;
10         try
11         {
12             if(!flag)
13                 group.threadStartFailed(this);
14         }
15         catch(Throwable throwable) { }
16         break MISSING_BLOCK_LABEL_70;
17         Exception exception;
18         exception;
19         try
20         {
21             if(!flag)
22                 group.threadStartFailed(this);
23         }
24         catch(Throwable throwable1) { }
25         throw exception;
26     }
27 
28     private native void start0();

二、实现Runnable接口创建线程

如果自己的类已经extends另一个类,就无法直接extends Thread,此时,可以实现一个Runnable接口,如下:

1 public class MyThread extends OtherClass implements Runnable {  
2   public void run() {  
3    System.out.println("MyThread.run()");  
4   }  
5 }  

为了启动MyThread,需要首先实例化一个Thread,并传入自己的MyThread实例:

1 MyThread myThread = new MyThread();  
2 Thread thread = new Thread(myThread);  
3 thread.start()

事实上,当传入一个Runnable target参数给Thread后,Thread的run()方法就会调用target.run(),参考JDK源代码:

1 public void run() {  
2   if (target != null) {  
3    target.run();  
4   }  
5 }  

这里应用了典型的回掉函数,A调用B,B在调用A,在定义一个接口定义准则,确定规范。

三,匿名函数创建

匿名函数必须要继承父类或者实现接口的。

有时候我们只用一次的话那么就可以用匿名函数了。

1 new Thread() {//创建方式1
2     public void run() {
3         for(int x=0; x<50; x++) {        
4             System.out.println(Thread.currentThread().getName()+"....x="+x);
5         }
6     }
7 }.start();
1 new Thread(new Runnable() {//创建方式2
2     public void run() {    
3         for(int x=0; x<50; x++) {        
4             System.out.println(Thread.currentThread().getName()+"....z="+x);
5         }
6     }
7 }).start();

 

 四,创建带返回值的多线程

一:创建自己的对象实现Callable<Object> 接口
二:重写call方法
三:创建线程池
四:通过线形池submit返回future对象
五:通过future获取任务的返回值
六:关闭线程

 1 public class CallableFutureTest {
 2     public static void main(String[] args) throws ExecutionException, InterruptedException {
 3         CallableFutureTest test = new CallableFutureTest();
 4         // 创建一个线程池
 5         ExecutorService pool = Executors.newFixedThreadPool(2);
 6         // 创建两个有返回值的任务
 7         Callable c1 = test.new MyCallable("A");
 8         Callable c2 = test.new MyCallable("B");      
 9         // 执行任务并获取Future对象
10         Future f1 = pool.submit(c1);
11         Future f2 = pool.submit(c2);       
12         // 从Future对象上获取任务的返回值,并输出到控制台
13         System.out.println(">>>" + f1.get().toString());
14         System.out.println(">>>" + f2.get().toString());       
15         // 关闭线程池
16         pool.shutdown();
17     }
18     class MyCallable implements Callable {
19         private String oid;
20         MyCallable(String oid) {
21             this.oid = oid;
22         }
23         public Object call() throws Exception {
24             return oid + "任务返回的内容";
25         }
26     }
27     }

 

五,spring创建多线程

加载xml文件
在ApplicationContext.xml文件里面添加

1 xmlns:task="http://www.springframework.org/schema/task" 

 xmlns文件并且xsi:schemaLocation中添加

1 http://www.springframework.org/schema/task 
1 http://www.springframework.org/schema/task/spring-task.xsd

在spring中配置Executor
在ApplicationContext.xml文件里面添加

 1 <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
 2         <!-- 核心线程数 -->     
 3         <property name="corePoolSize" value="${task.core_pool_size}" />
 4         <!-- 最大线程数 -->  
 5         <property name="maxPoolSize" value="${task.max_pool_size}" />
 6         <!-- 队列最大长度 -->
 7         <property name="queueCapacity" value="${task.queue_capacity}" />
 8         <!-- 线程池维护线程所允许的空闲时间,默认为60s -->
 9         <property name="keepAliveSeconds" value="${task.keep_alive_seconds}" />
10     </bean>
11     <!-- 注解式 -->
12     <task:annotation-driven />

在dbconfig.properties添加

1 maxOpenPreparedStatements=20
2 removeAbandoned=true
3 removeAbandonedTimeout=1800
4 logAbandoned=true
这是分别对线程池做配置
 

添加依赖注入
在所需要的service或者controller类里面添加

1 @Resource(name = "taskExecutor")
2 private TaskExecutor taskExecutor;

使用线程池进行并发操作
代码如下

 1             taskExecutor.execute(new Runnable() {
 2  
 3                 @Override
 4                 public void run() {
 5                     // TODO Auto-generated method stub
 6                     try {
 7                                           //要进行的并发操作
 8                     } catch (Exception e) {
 9                         // TODO Auto-generated catch block
10                         e.printStackTrace();
11                     }
12                 }
13             });

提示

注意在线程中操作变量时候变量的作用域范围。需要在这个controller或者sevice中声明变量如下
 1 @Controller
 2 public class IndexController {
 3 int studentscount = 0;
 4 @RequestMapping(value = "/index.html")
 5     public ModelAndView goIndex() {
 6         logBefore(logger, "列表Center");
 7         ModelAndView mv = this.getModelAndView();
 8                 taskExecutor.execute(new Runnable() {
 9  
10                 @Override
11                 public void run() {
12                     // TODO Auto-generated method stub
13                     // 得到所有学生人数
14                     try {
15                                           studentscount = coursesService.getStudentCount(pd);
16                     } catch (Exception e) {
17                         // TODO Auto-generated catch block
18                         e.printStackTrace();
19                     }
20  
21                 }
22             });
23                   mv.addObject("studentscount", studentscount);
24                   mv.setViewName("common/index");
25                   return mv;
26

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值