超链接没有反应
462
2022-05-29
今天学完了华为云课堂java多线程实战中创建线程这一章,做一个小结,巩固新知
一、进程和线程的理解
进程和线程专业的术语我并不能记下来,但是通过自己的理解也对两者的关系和区别有了一定的认识。
首先介绍两者关系。打开任务管理器,可以看见已经启动的应用程序,每一个应用程序就是一个进程,比如qq。当我们在使用qq的某些功能如语音、视频时,我们其实就是在使用qq的线程,也就是说一个应用程序就是一个进程,而应用程序中的各个功能就是线程。进程和线程之间的关系就可以理解成父母和子女的关系,进程是父母,线程则是子女。父母可以没有子女而独立存在,而子女的存在离不开父母。
两者的区别可以从地址空间、资源拥有、执行过程三反面描述,表格如下
二、创建线程的五种方式
1.继承Thread()类
通过继承Thread()类并重写run()方法,run()方法是中心方法,里面放着需要执行的任务,关键就是这个run()函数
创建后的子类调用start()方法就可以执行线程中的run()方法
注意:这种继承Thread()类创建的线程类,多个线程间无法共享线程类的实例变量
public class UserThread extends Thread{ @Override public void run() { for(int i = 0;i<10;i++) { System.out.println(Thread.currentThread().getName()+"is running"+i); //得到正在执行任务的线程的名称 } } }
public class UserThreadTest { public static void main(String[] args) { // TODO Auto-generated method stub Thread t1 = new UserThread();//通过继承Thread类创建的线程类,线程不共享资源 Thread t2 = new UserThread(); t1.start(); t2.start(); //两个线程同时执行任务 } }
2.实现Runnable接口
先定义一个类实现Runnable接口并重写run()方法,run()是线程的执行体,是关键方法
创建Runnable实现类的对象
创建Thread()对象,将先前创建的Runnable实现类的对象作为参数传入到Thread()对象中,Thread()对象才是真正的线程对象
注意:利用Runnable创建的线程类对象,线程可以共享资源
public class UserRun implements Runnable{ @Override public void run() { // TODO Auto-generated method stub for(int i = 0;i<10;i++) { System.out.println(Thread.currentThread().getName()+"is Running"+i); } } }
public class UserRunTest { public static void main(String[] args) { // TODO Auto-generated method stub UserRun userRun = new UserRun(); Thread t1 = new Thread(userRun); Thread t2 = new Thread(userRun); t1.start(); t2.start(); //两个线程同时进行 } }
3.实现Callable接口实现带有返回值的线程
Callable接口相当于Runnable接口的升级版,其中call()方法是执行体,和run()方法作用相同,只不过带有了返回值
Callable对象不能作为Thread()的参数,这是和Runnable的区别,Callable接口不是Runnable接口的子接口
解决这个问题,引入Future接口,这个接口可以接收call()的返回值,RunnableFuture接口是Future接口和Runnable接口的子接口,可以作为Thread对象的参数
import java.util.concurrent.Callable; public class UserCallable implements Callable{ @Override public Object call() throws Exception { System.out.println(Thread.currentThread().getName()); return "学习"; } }
import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; import java.util.concurrent.RunnableFuture; public class UserCallableTest { public static void main(String[] args) throws InterruptedException, ExecutionException { // TODO Auto-generated method stub UserCallable user = new UserCallable(); FutureTask ft = new FutureTask(user);//引入Future接口,可以作为Thread()的参数,Future接口可以接受call()的返回值 Thread t = new Thread(ft); t.start(); System.out.println(ft.get());//得到call()返回值 } }
4.继承TimerTask抽象父类
Timer和TimerTask是可以产生线程类的方法。Timer是一种线程设施,可以调度TimerTask,安排后台程序中执行的任务,任务可以执行一次或定期重复执行,相当于一个定时器
创建线程的步骤
定义UserTask类继承TimerTask
创建UserTask对象
创建Timer类对象,设置执行策略
import java.util.Date; import java.util.TimerTask; public class UserTask extends TimerTask{ @Override public void run() { // TODO Auto-generated method stub System.out.println(Thread.currentThread().getName()+"is running"+new Date()); } }
import java.util.Timer; public class UserTaskTest { public static void main(String[] args) { // TODO Auto-generated method stub UserTask ut = new UserTask(); Timer t = new Timer(); t.schedule(ut, 2000, 1000); } }
三、总结
好啦,这部分就写到这了,该去吃饭了,简单来说这篇文章写了进程和线程的联系和区别以及创建线程的几种方法,重点是通过继承Thread类创建线程类和实现Runnable接口创建线程类这两种方法。收获满满,继续努力。
Java 培训服务
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。