Python 官方文档:入门教程 => 点击学习
进程与线程 进程可以简单理解成一个可执行程序例如.exe,在windows中的任务管理器中可以查看每一个进程,进程是一次程序的执行,是程序在数据集合上运行的过程,是系统资源调度的一
进程可以简单理解成一个可执行程序例如.exe,在windows中的任务管理器中可以查看每一个进程,进程是一次程序的执行,是程序在数据集合上运行的过程,是系统资源调度的一个单位。进程主要负责向操作系统申请资源。然而一个进程中,多个线程可以共享进程中相同的内存或文件资源。线程就是一个进程一个程序要完成所依赖的子任务,这些子任务便可以看作是一个线程。
从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方法便结束线程。
相比继承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接口使用方法和Runnable接口的方法类似不同的一点是Callable接口具有返回值,返回结果并且可能抛出异常的任务。实现者定义了一个不带任何参数的叫做 call 的方法。 Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。
实现代码
对下列代码进行分析
首先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<Object> {//不能直接创建线程
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;
}
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())+"毫秒");
}
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的方法。线程和数据库连接这些资源都是非常宝贵的资源。那么每次需要的时候创建,不需要的时候销毁,是非常浪费资源的。那么我们就可以使用缓存的策略,也就是使用线程池。
// 创建线程池
ExecutorService threadPool = Executors.newFixedThreadPool(10);
while(true) {
threadPool.execute(new Runnable() { // 提交多个线程任务,并执行
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " is running ..");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
} }
理论上实现线程的方法还有一些,本文所提及到的,基本都是一些创建线程常用的方法。希望本文对大家在学习线程的过程中有所帮助。
--结束END--
本文标题: java实现/创建线程的几种方式小结
本文链接: https://lsjlt.com/news/132089.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0