当前位置: 首页 > news >正文

分类网站模板/站内优化

分类网站模板,站内优化,网站编写语言什么好,找考卷做要去哪个网站java线程的创建与实现 进程与线程 进程可以简单理解成一个可执行程序例如.exe,在Windows中的任务管理器中可以查看每一个进程,进程是一次程序的执行,是程序在数据集合上运行的过程,是系统资源调度的一个单位。进程主要负责向操作…

java线程的创建与实现

进程与线程
进程可以简单理解成一个可执行程序例如.exe,在Windows中的任务管理器中可以查看每一个进程,进程是一次程序的执行,是程序在数据集合上运行的过程,是系统资源调度的一个单位。进程主要负责向操作系统申请资源。然而一个进程中,多个线程可以共享进程中相同的内存或文件资源。线程就是一个进程一个程序要完成所依赖的子任务,这些子任务便可以看作是一个线程。
在这里插入图片描述

第一种方式继承Thread类

从java源码可以看出Thread类本质上实现了Runnable接口的实例类,代表了线程的一个线程的实例,启动的线程唯一办法就是通过Thread类调用start()方法,start()方法是需要本地操作系统的支持,它将启动一个新的线程,并且执行run()方法。
在这里插入图片描述

继承Thread类实现线程代码如下

创建一个Thread类,对象直接调用run方法会出现什么问题?

package cn.thread.线程;public class MyThread extends Thread{public MyThread(String name){super(null,null,name);}int piao =10;@Overridepublic void run() {while(piao>0){System.out.println(Thread.currentThread().getName()+"......"+piao--);}}public static void main(String[] args) {MyThread mt = new MyThread("x");mt.run();}
}

结果:
可以发现是主线程执行了run方法,并不是用户线程执行的run方法,此时可以得出用户线程并没有启动,所以并不会执行run里面的方法,且执行完run方法便结束线程。
在这里插入图片描述

第二种创建线程的方法,实现Runnable接口

相比继承Thread类而言,实现接口的可扩展性得到了提升,Runnable接口也必须要封装到Thread类里面,才可以调用start方法,启动线程。

实现代码
package cn.thread.线程;public class MyRunnable implements Runnable{int piao = 10;@Overridepublic void run() {while(piao>0){System.out.println(Thread.currentThread().getName()+"-----"+piao--);}}public static void main(String[] args) {Runnable r =new MyRunnable();Thread t =new Thread(r);t.start();}}

结果
在这里插入图片描述

第三种创建线程的方法实现Callable接口

Callable接口使用方法和Runnable接口的方法类似不同的一点是Callable接口具有返回值,返回结果并且可能抛出异常的任务。实现者定义了一个不带任何参数的叫做 call 的方法。 Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。 Executor线程池的超类:执行已提交的 Runnable 任务的对象。此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节、调度等)分离开来的方法。通常使用 Executor 而不是显式地创建线程。例如,可能会使用以下方法,而不是为一组任务中的每个任务调用 new Thread(new(RunnableTask())).start():

实现代码

对下列代码进行分析
首先callable是接口不能直接创建对象,也不能创建线程。并且要实现call方法类似run方法的功能,call方法有返回值,会计算结果,如果无法计算结果,则抛出一个异常。
执行callable任务之后,可以获得一个future的对象,future基本上是主线程可以跟踪进度以及获取其他线程结果的一种方式。在这里Test1()方法主要利用线程池和future的方法,去启动实现Callable接口的线程,具有返回值。而Test2()主要是采用FutureTask类去实现创建一个实现callable接口的线程,futuretask实现了future接口。

package com.openlab.test;import java.util.Random;
import java.util.concurrent.Callable;public class CallableTest implements Callable{@Overridepublic Object call() throws Exception {Random generator = new Random();Integer randomNumber = generator.nextInt(5);Thread.sleep(randomNumber*1000);return randomNumber;}}

综合练习代码:

package cn.thread.线程;import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;public class CallableTest implements Callable<Object> {//不能直接创建线程int taskNum;public CallableTest(int taskNum){this.taskNum = taskNum;}@Overridepublic Object call() throws Exception {System.out.println(">>>"+taskNum+"任务启动");Date dataTemp = new Date();Thread.sleep(1000);Date dataTemp2 = new Date();long time  = dataTemp2.getTime() - dataTemp.getTime();System.out.println(">>>>"+taskNum+"任务终止");return taskNum+"任务返回运行结果"+time;
//        Random generator = new Random();
//        Integer randomNumber = generator.nextInt(5);
//        Thread.sleep(randomNumber*1000);
//        return  randomNumber;}/*test1方法采用Executors的静态方法newFixedThreadPool(taskSize) 创建一个可重用固定线程集合的线程池,以共享的无界队列方式来运行这些线程,获取线程池。ExecutorService的submit方法提交一个callable实例,得到一个future对象,最终将future对象存储在list数组中,加入线程池的过程中就代表着线程已经开始执行,相当于一个线程池代理过程,就不需要采用start方法启动线程。最后对future进行打印输出。切记一定要关闭线程池!*/static void test1() throws ExecutionException, InterruptedException {System.out.println("程序开始");Date data1 = new Date();int taskSize = 5;//构建线程池对象ExecutorService pool = Executors.newFixedThreadPool(taskSize);List<Future> list =new ArrayList<Future>();for(int i=0;i<taskSize;i++){Callable c = new CallableTest(i);Future f = pool.submit(c);list.add(pool.submit(c));}//关闭线程池pool.shutdown();for(Future f:list){System.out.println(">>>"+f.get().toString());}Date date2 = new Date();System.out.println("程序运行结束-----"+(date2.getTime()-data1.getTime())+"毫秒");}/*test2方法主要是采用futuretask类,可以直接把callable作为参数来申明futuretask对象,这里相当于把线程池换成了futuretask数组,因为test1线程池可以对callable进行封装,在这里可以直接采用futuretask就行封装,在加上futuretask又实现了runnable接口,所以可以直接创建线程采用start的方式进行启动线程。*/static  void test2() throws ExecutionException, InterruptedException {System.out.println("----程序开始-----");Date date1 =new Date();int taskSize = 5;FutureTask[] randNumber = new FutureTask[taskSize];List<Future> list =new ArrayList<Future>();for(int i=0;i<taskSize;i++){Callable c = new CallableTest(i);randNumber[i] = new FutureTask(c);Thread t = new Thread(randNumber[i]);t.start();}for(Future f:randNumber){System.out.println(">>>"+f.get().toString());}Date date2 = new Date();System.out.println("程序运行结束-----"+(date2.getTime()-date1.getTime())+"毫秒");}public static void main(String[] args) throws Exception {
//        CallableTest c = new CallableTest();
//        Integer i = (Integer) c.call();test1();test2();}
}

执行结果
在这里插入图片描述

第四种实现线程的方法,基于线程池

其实在第三种的方法中就提到了两种实现方法,一种线程池+future,另一种futuretask的方法。线程和数据库连接这些资源都是非常宝贵的资源。那么每次需要的时候创建,不需要的时候销毁,是非常浪费资源的。那么我们就可以使用缓存的策略,也就是使用线程池。

     static void test1() throws ExecutionException, InterruptedException {//借助线程池创建线程System.out.println("程序开始");Date data1 = new Date();int taskSize = 5;//构建线程池对象ExecutorService pool = Executors.newFixedThreadPool(taskSize);List<Future> list =new ArrayList<Future>();for(int i=0;i<taskSize;i++){Callable c = new CallableTest(i);Future f = pool.submit(c);list.add(pool.submit(c));}//关闭线程池pool.shutdown();for(Future f:list){System.out.println(">>>"+f.get().toString());}Date date2 = new Date();System.out.println("程序运行结束-----"+(date2.getTime()-data1.getTime())+"毫秒");}

Callable接口形式上和Runnable接口类似,区别在于Callable接口可以处理异常,以及可以拥有返回值。比Runnable更灵活,弊端在于Callable不能用Thread线程类进行封装,需要借助FutureTask类,FutuTask也实现了Runnable接口,初始化可以将Callable对象作为参数传入到FutureTask里,然后在采用Thread封装FutureTask。最后调用start()启动线程,此时线程会去执行Callable的call()方法里面的类容。

总结

理论上实现线程的方法还有一些,本文所提及到的,基本都是一些创建线程常用的方法。希望本文对大家在学习线程的过程中有所帮助。

http://www.lbrq.cn/news/961507.html

相关文章:

  • 东莞长安网站制作/百度权重优化软件
  • 为什么招聘网站做不大/百度关键词如何优化
  • jsp做简单校园网站/seo全网图文推广
  • android 旅游网站开发/沧州网站推广优化
  • 广州平面设计师招聘/aso优化技巧
  • 番禺网站制作价格/江苏网站seo
  • 陕西城乡住房建设厅网站/网站推广营销
  • 岳阳网站建设 熊掌号/新开店铺怎么做推广
  • 政府网站制作方案/西安专业网络推广公司
  • 网站怎么做360免费优化/品牌网络推广外包
  • 西安网站设计锦/百度老年搜索
  • 建设网站网页打不开/win10优化
  • wordpress 查件/搜索引擎推广seo
  • 有什么好的设计网站/企业推广网站
  • 做网站建设的公司/seo咨询顾问
  • mui做的h5网站案例/大量微信群推广代发广告
  • 哪个网站教做西餐/玉林seo
  • 网站流程/杭州产品推广服务公司
  • 网站专栏建设情况/优化大师有必要安装吗
  • 网站建设项目需求分析/商业软文
  • 网站后台上传木马教程/免费创建个人网站
  • 国外网站做淘宝客/免费推广途径与原因
  • 宿迁做网站优化/电商怎么注册开店
  • wordpress页面内导航/湖南正规关键词优化首选
  • 在线图片制作生成/seo网络推广优化
  • 深圳网站备案拍照点/许昌seo推广
  • 网站引导页怎么设置/seo资源
  • 计算机培训班要学多久/沈阳企业网站seo公司
  • 图跃网站建设/网站建设的重要性
  • 东莞 网站 建设/5g影讯5g天线在线观看免费视频
  • 大模型格式
  • 用线性代数推导码分多址(CDMA)
  • 记录DataGrip 2025.1.3破解失败后,无法重启问题修复
  • Excel批量生成SQL语句 Excel批量生成SQL脚本 Excel拼接sql
  • 【怜渠客】简单实现手机云控Windows电脑锁屏
  • 无符号乘法运算的硬件逻辑实现 ————取自《湖科大教书匠》