java线程实现/创建的几种方式

您所在的位置:网站首页 java显示日期的几种形式有哪些 java线程实现/创建的几种方式

java线程实现/创建的几种方式

2024-07-13 16:31| 来源: 网络整理| 查看: 265

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; @Override public 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; @Override public 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{ @Override public 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 {//不能直接创建线程 int taskNum; public CallableTest(int taskNum){ this.taskNum = taskNum; } @Override public 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 list =new ArrayList(); for(int i=0;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3