java中实现多线程的方法有两种:继承Thread类和实现runnable接口

1.继承Thread类,重写父类run()方法

public class thread1 extends Thread {

   public void run() {
for (int i = 0; i < 10000; i++) {
System.out.println("我是线程"+this.getId());
}
} public static void main(String[] args) {
thread1 th1 = new thread1();
thread1 th2 = new thread1();
th1.run();
th2.run();
}
}

run()方法只是普通的方法,是顺序执行的,即th1.run()执行完成后才执行th2.run(),这样写只用一个主线程。多线程就失去了意义,所以应该用start()方法来启动线程,start()方法会自动调用run()方法。上述代码改为:

public class thread1 extends Thread {

    public void run() {
for (int i = 0; i < 10000; i++) {
System.out.println("我是线程"+this.getId());
}
} public static void main(String[] args) {
thread1 th1 = new thread1();
thread1 th2 = new thread1();
th1.start();
th2.start();
}
}

通过start()方法启动一个新的线程。这样不管th1.start()调用的run()方法是否执行完,都继续执行th2.start()如果下面有别的代码也同样不需要等待th2.start()执行完成,而继续执行。(输出的线程id是无规则交替输出的)

2.实现runnable接口

public class thread2 implements Runnable {

    public String ThreadName;

    public thread2(String tName){
ThreadName = tName;
} public void run() {
for (int i = 0; i < 10000; i++) {
System.out.println(ThreadName);
}
} public static void main(String[] args) {
thread2 th1 = new thread2("线程A");
thread2 th2 = new thread2("线程B");
th1.run();
th2.run();
}
}

和Thread的run方法一样Runnable的run只是普通方法,在main方法中 th2.run()必须等待th1.run()执行完成后 才能执行,程序只用一个线程。要多线程的目的,也要通过Thread的start()方法(注:runnable是没有start方法)。上述代码修改 为:

public class thread2 implements Runnable {

    public String ThreadName;

    public thread2(String tName){
ThreadName = tName;
} public void run() {
for (int i = 0; i < 10000; i++) {
System.out.println(ThreadName);
}
} public static void main(String[] args) {
thread2 th1 = new thread2("线程A");
thread2 th2 = new thread2("Thread-B");
Thread myth1 = new Thread(th1);
Thread myth2 = new Thread(th2);
myth1.start();
myth2.start();
}
}

3.使用ExecutorService、Callable、Future实现有返回结果的多线程(JDK5.0以后)
可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口。执行Callable任务后,可以获
取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了,再结合线程池接口
ExecutorService就可以实现传说中有返回结果的多线程了。下面提供了一个完整的有返回结果的多线程测试例子,在JDK1.5下验证过没问题
可以直接使用。代码如下:

import java.util.concurrent.*;
import java.util.Date;
import java.util.List;
import java.util.ArrayList; /**
* 有返回值的线程
*/
@SuppressWarnings("unchecked")
public class Test {
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()方法,会阻塞直到计算完成。

Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。

Callable和Runnable有几点不同:、

①Callable规定的方法是call(),而Runnable规定的方法是run().
        ②Callable的任务执行后可返回值,而Runnable的任务是不能返回值的
        ③call()方法可抛出异常,而run()方法是不能抛出异常的。
        ④运行Callable任务可拿到一个Future对象,Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等

待计算的完成,并检索计算的结果.通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果

总结:实现java多线程的2种方式,runable是接口,thread是类,runnable只提供一个run方法,建议使用runable实现 java多线程,不管如何,最终都需要通过thread.start()来使线程处于可运行状态。

3种方式实现Java多线程的更多相关文章

  1. java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明)

    转载地址:http://www.devba.com/index.php/archives/4581.html java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明); ...

  2. (转)java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明)

    java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明);部分资料参考网络资源 1. java向MySQL插入当前时间的四种方式 第一种:将java.util.Date ...

  3. 两种方式实现java生成Excel

    Web应用中难免会遇到需要将数据导出并生成excel文件的需求.同样,对于本博客中的总结,也是建立在为了完成这样的一个需求,才开始去了解其实现形式,并且顺利完成需求的开发,先将实现过程总结于此.本博文 ...

  4. Struts 2 实现Action的几种方式_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 Action用于处理用户的请求,因此也被称为业务控制器.每个Action类就是一个工作单元,Struts 2框架负责将用 ...

  5. 五种方式实现 Java 单例模式

    前言 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的类,该类负责创建自 ...

  6. 设置JVM参数的几种方式解决java.lang.OutOfMemoryError:Java heap space

    一.首先给出查询当前JVM内存的代码: 下面是查询当前JVM 内存大小的代码,可以测试设置后JVM 的内存是否会变化.增加JVM 内存的配置项后,无需重新启动eclipse .具体的代码如下: pub ...

  7. java 下载文件的两种方式和java文件的上传

    一:以网络的方式下载文件 try { // path是指欲下载的文件的路径. File file = new File(path); // 以流的形式下载文件. InputStream fis = n ...

  8. (分享)java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明)

    原文地址 http://blog.csdn.net/yangkai_hudong/article/details/18705713

  9. 3种方式实现python多线程并发处理

    标签: python奇淫技巧 最优线程数 Ncpu=CPU的数量 Ucpu=目标CPU使用率 W/C=等待时间与计算时间的比率 为保持处理器达到期望的使用率,最优的线程池的大小等于$$Nthreads ...

随机推荐

  1. clipse在编写JSP时没有代码提示

    alt /不会出提示按照下面步骤做 1.菜单window- >Preferences- >Java- >Editor- >Content Assist- >Enable ...

  2. TestNG:org.openqa.selenium.firefox.NotConnectedException: Unable to connect

    http://blog.sina.com.cn/s/blog_68f262210102vgzj.html 今天在尝试着用TestNG写一下自动化测试用例,以前也写过,不过用的是经常封装的代码,现在完全 ...

  3. uWSGI其三:uWSGI搭配Nginx使用

    http://www.nowamagic.net/academy/detail/1330334 上一篇介绍了 uWSGI 来部署 Django 程序,但在在生产环境中单单只有 uWSGI 是不够的,N ...

  4. nyoj 86 找球号(一)

    点击打开链接 找球号(一) 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 在某一国度里流行着一种游戏.游戏规则为:在一堆球中,每个球上都有一个整数编号i(0<=i ...

  5. 用HTML代码加载Unity内容(unity频道:http://unity3d.9ria.com/)

    Unity内容在浏览器通过Unity网络播放器插件加载.HTML代码与这个插件通常不直接通信,而是通过UnityObject的脚本帮助.其主要任务是Unity的内容嵌入一个非常简单的任务,通过从各种浏 ...

  6. (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在

    问题描述:在用vs生成MVC时若使用Internet应用程序为模版,项目建好后重新编译下无法通过,弹出错误: 解决方案:问题出来后,询问了身边很多人都是一头雾水,于是乎各种谷歌和百度,还好功夫不负有心 ...

  7. MySQL常用命令(待更新)

    1.登录到mysql:mysql -hlocalhost -uroot -p2.创建数据库:create database:3.使用数据库:use database:4.创建表:人员:qacreate ...

  8. 从AlphaGo谈通用型人工智能设计

    最近赢了人机大战的AlphaGo火了,火得一塌糊涂,圈里圈外,是人都在谈AlphaGo.但是AlphaGo毕竟是为特定场景特定应用设计的特定型人工智能,和通用型人工智能还是有很大差别,离人工智能普及更 ...

  9. unity区分点击在3D物体还是2D UI上

    当场景中的3D物体需要响应点击,但同时有UI显示时,存在判断点击是在3D物体上还是UI上的问题,办法如下: 1. 射线检测所有2D 3D物体,有2D物体被检测到时表明当前有UI.但无论Physics2 ...

  10. oracle修改连接空闲自动断开

    空闲3分钟自动断开 SELECT * FROM DBA_PROFILES; CREATE PROFILE KILLIDLE LIMIT IDLE_TIME ; alter PROFILE DEFAUL ...