Java多线程的应用总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程的应用总结相关的知识,希望对你有一定的参考价值。
多线程的好处 : 在java中通常每一个任务称为一个线程,但是多线程实现一个程序同时执行多个任务。
直接了当的说多线程可以把任务分块执行,分块后可以同时进行而不用等待。 如下载文件,
浏览网站时加载图片,通过多线程就可以实现多文件下载,一下做好几个工作,这样效率更高,
Java多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返 回值的。
给大家写了一个利用多线程编程的小球在界面内循环跳动代码如下:(可复制到开源工具查看效果)
package com.kd; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Super3 { public static void main(String[] args) { JFrame frame = new BounceThreadFrame(); frame.show(); } } class BounceThreadFrame extends JFrame { public BounceThreadFrame() { setSize(300, 200); setTitle("Bounce"); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); Container contentPane = getContentPane(); canvas = new JPanel(); contentPane.add(canvas, "Center"); JPanel p = new JPanel(); addButton(p, "Start", new ActionListener() { public void actionPerformed(ActionEvent evt) { Ball b = new Ball(canvas); b.start(); } }); addButton(p, "Close", new ActionListener() { public void actionPerformed(ActionEvent evt) { canvas.setVisible(false); System.exit(0); } }); contentPane.add(p, "South"); } public void addButton(Container c, String title, ActionListener a) { JButton b = new JButton(title); c.add(b); b.addActionListener(a); } private JPanel canvas; } class Ball extends Thread { public Ball(JPanel b) { box = b; } public void draw() { Graphics g = box.getGraphics(); g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); } public void move() { if (!box.isVisible()) return; Graphics g = box.getGraphics(); g.setXORMode(box.getBackground()); g.fillOval(x, y, XSIZE, YSIZE); x += dx; y += dy; Dimension d = box.getSize(); if (x < 0) { x = 0; dx = -dx; } if (x + XSIZE >= d.width) { x = d.width - XSIZE; dx = -dx; } if (y < 0) { y = 0; dy = -dy; } if (y + YSIZE >= d.height) { y = d.height - YSIZE; dy = -dy; } g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); } public void run() { try { draw(); for (int i = 1; i <= 1000; i++) { move(); sleep(5); } } catch(InterruptedException e) {} } private JPanel box; private static final int XSIZE = 10; private static final int YSIZE = 10; private int x = 0; private int y = 0; private int dx = 2; private int dy = 2; }
还可以利用多线程做GIF转动图
使用ExecutorService、Callable、Future实现有返回结果的多线程代码如下:
package com.kd; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * Java线程:有返回值的线程 * * @author wb_qiuquan.ying */ @SuppressWarnings("unchecked") public class Super4 { public static void main(String[] args) throws ExecutionException, InterruptedException { System.out.println("----程序开始运行----"); Date date1 = 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 MyCallable(i + " "); // 执行任务并获取Future对象 Future f = pool.submit(c); // System.out.println(">>>" + f.get().toString()); list.add(f); } // 关闭线程池 pool.shutdown(); // 获取所有并发任务的运行结果 for (Future f : list) { // 从Future对象上获取任务的返回值,并输出到控制台 System.out.println(">>>" + f.get().toString()); } Date date2 = new Date(); System.out.println("----程序结束运行----,程序运行时间【" + (date2.getTime() - date1.getTime()) + "毫秒】"); } } class MyCallable implements Callable<Object> { private String taskNum; MyCallable(String taskNum) { this.taskNum = taskNum; } public Object call() throws Exception { System.out.println(">>>" + taskNum + "任务启动"); Date dateTmp1 = new Date(); Thread.sleep(1000); Date dateTmp2 = new Date(); long time = dateTmp2.getTime() - dateTmp1.getTime(); System.out.println(">>>" + taskNum + "任务终止"); return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】"; } }
代码说明: 上述代码中Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。 public static ExecutorService newFixedThreadPool(int nThreads) 创建固定数目线程的线程池。 public static ExecutorService newCachedThreadPool() 创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。 public static ExecutorService newSingleThreadExecutor() 创建一个单线程化的Executor。 public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。
以上是关于Java多线程的应用总结的主要内容,如果未能解决你的问题,请参考以下文章