并行: 多个CPU同时执行多个任务。 如:多个人同时做不同的事情。 并发: 一个CPU(采用时间片)同时执行多个任务。 当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。这就是并发 JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。 控制台结果: 创建一个实现了Runnable接口的类 实现类去实现Runnable中的抽象方法:run() 创建实现类的对象 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象 通过Thread类的对象调用start() 控制台输出结果: **注意点:**事实上,当传入一个Runnable target参数给Thread后,Thread的run()方法就会调用target.run(),参考JDK源代码: 如何理解实现Callable接口的方式创建多线程比实现Runnable接口创建多线程方式强大? 控制台结果: 方法: 控制台结果: 代码解释来自作者:wb_qiuquan.ying 今天莫名看到。 上述代码中Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。 ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。Java4种多线程的创建:
什么是程序?
什么是进程?
什么是线程?
并行与并发:
那么JAVA多线程实现方式:
(1)继承Thread类实现多线程:
public class ThreadTest extends Thread{ //创建一个继承于Thread类的子类 //重写Thread类的run() --> 将此线程执行的操作声明在run()中 @Override public void run(){ System.out.println("这是:[" + getName() + "]的启动"); } public static void main(String[] args) { //创建Thread类的子类的对象 ThreadTest thread1 = new ThreadTest(); ThreadTest thread2 = new ThreadTest(); thread1.setName("线程一");//给线程设置名字 thread2.setName("线程二"); thread1.start();//通过线程子类对象调用start() thread2.start(); } }
这是:[线程一]的启动。 这是:[线程二]的启动。 Process finished with exit code 0 可知启动了两个线程
(2)实现Runnable接口方式实现多线程:
//创建一个实现了Runnable接口的类 public class RunnableStart extends Thread implements Runnable { //实现类去实现Runnable中的抽象方法:run() @Override public void run() { System.out.println("这是:[" + Thread.currentThread().getName() + "]的启动"); } public static void main(String[] args) { // 创建实现类的对象 RunnableStart runnableThread = new RunnableStart(); // 将实现类对象作为参数传递到Thread类的构造器中,创建Thread类的对象 Thread thread1 = new Thread(runnableThread); Thread thread2 = new Thread(runnableThread); thread1.setName("Runnable方式线程一:");//设置线程的名字 thread2.setName("Runnable方式线程二:"); // 通过Thread类的对象调用start() thread1.start(); thread2.start(); } }
这是:[Runnable方式线程二:]的启动 这是:[Runnable方式线程一:]的启动 Process finished with exit code 0
public void run() { if (target != null) { target.run(); } }
(3)实现callable方式:(比实现Runnable方式强大)
//1.创建一个实现Callable的实现类 class CallThread implements Callable { //2.实现call方法,将此线程需要执行的操作声明在call()中 @Override public Object call() throws Exception { int sum = 0; for (int i = 1; i <= 100; i++) { if (i % 2 == 0) { sum += i;//计算100以内偶数之和 } } return sum; } } public class ThreadTest { public static void main(String[] args) throws Exception { //3.创建Callable接口实现类的对象 CallThread callThread = new CallThread(); //4.将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象 FutureTask futureTask = new FutureTask(callThread); //5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start() Thread thread = new Thread(futureTask); thread.start(); //6.获取Callable中call方法的返回值 //get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值。 Object sum = futureTask.get(); System.out.println("实现Callable方式的返回值总和为:" + sum); } }
实现Callable方式的返回值总和为:2550 Process finished with exit code 0
(4)使用ExecutorService、Future(线程池):实现有返回结果的多线程:
public class ThreadPoolTest { public static void main(String[] args) throws Exception { System.out.println("----程序开始运行----"); Date start = new Date();//开始时间 // 创建一个指定数量的线程池 ExecutorService pool = Executors.newFixedThreadPool(10); // 创建多个有返回值的任务 List<Future> list = new ArrayList<>(); for (int i = 0; i < 10; i++) {//因为只设有限定10个线程 Callable call = new TestCallable(i + " "); // 执行任务并获取Future对象 Future f = pool.submit(call); list.add(f); } // 关闭线程池 pool.shutdown(); // 获取所有并发任务的运行结果 for (Future f : list) { // 从Future对象上获取任务的返回值,并输出到控制台 System.out.println(">>>" + f.get().toString()); } Date end = new Date();//结束时间 System.out.println("----程序结束运行----,程序运行时间【" + (end.getTime() - start.getTime()) + "毫秒】");//计算出来的总运行时间 } } class TestCallable implements Callable<Object> { private String taskNum;//任务编号 TestCallable(String taskNum) { this.taskNum = taskNum; } @Override public Object call() throws Exception { System.out.println(">>>" + taskNum + "任务启动"); Date dateStart = new Date();//开始时间 Thread.sleep(1000);//阻塞1000毫秒 Date dateEnd = new Date();//结束时间 long time = dateEnd.getTime() - dateStart.getTime(); System.out.println(">>>" + taskNum + "任务终止"); return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】"; } }
----程序开始运行---- >>>0 任务启动 >>>3 任务启动 >>>2 任务启动 >>>1 任务启动 >>>4 任务启动 >>>5 任务启动 >>>6 任务启动 >>>8 任务启动 >>>7 任务启动 >>>9 任务启动 >>>4 任务终止 >>>2 任务终止 >>>1 任务终止 >>>3 任务终止 >>>5 任务终止 >>>0 任务终止 >>>0 任务返回运行结果,当前任务时间【1001毫秒】 >>>1 任务返回运行结果,当前任务时间【1001毫秒】 >>>2 任务返回运行结果,当前任务时间【1001毫秒】 >>>3 任务返回运行结果,当前任务时间【1001毫秒】 >>>4 任务返回运行结果,当前任务时间【1001毫秒】 >>>5 任务返回运行结果,当前任务时间【1001毫秒】 >>>8 任务终止 >>>6 任务终止 >>>7 任务终止 >>>6 任务返回运行结果,当前任务时间【1001毫秒】 >>>7 任务返回运行结果,当前任务时间【1001毫秒】 >>>9 任务终止 >>>8 任务返回运行结果,当前任务时间【1001毫秒】 >>>9 任务返回运行结果,当前任务时间【1001毫秒】 ----程序结束运行----,程序运行时间【1005毫秒】
线程池方式代码说明:
public static ExecutorService newFixedThreadPool(int nThreads)
创建固定数目线程的线程池。
public static ExecutorService newCachedThreadPool()
创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
public static ExecutorService newSingleThreadExecutor()
创建一个单线程化的Executor。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
总结:就是4种线程的创建方式,以及简单的介绍线程。如有其他问题可以找我。
作者公众号:小白编码,欢迎大家关注一起学习。
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算