1.继承Thread类

 class MyThread extends Thread{
private int ticket = 5 ;
public void run(){
for(int i=0;i<100;i++){
if(this.ticket>0){
System.out.println("卖票:ticket = " + ticket--) ;
}
}
}
};
public class ThreadDemo0{
public static void main(String args[]){
MyThread mt1 = new MyThread() ;
MyThread mt2 = new MyThread() ;
MyThread mt3 = new MyThread() ;
mt1.run() ; //注意:调用的是run,并不是start
mt2.run() ;
mt3.run() ;
}
};

class Mythread extends Thread{
private int ticket = 5 ;
public void run(){
for(int i=0;i<100;i++){
if(this.ticket>0){
System.out.println("卖票:ticket = " + ticket--) ;
}
}
}
};
public class ThreadDemo0{
public static void main(String args[]){
Mythread mt1 = new Mythread() ;
Mythread mt2 = new Mythread() ;
Mythread mt3 = new Mythread() ;
mt1.start();
mt2.start();
mt3.start();
}
};

:start()用来启动一个线程,当调用start()方法时,系统才会开启一个线程,通过Thead类中start()方法来启动的线程处于就绪状态(可运行状态),
此时并没有运行,一旦得到CPU时间片,就自动开始执行run()方法。此时不需要等待run()方法执行完也可以继续执行下面的代码,
而run()方法是在本线程里的,只是线程里的一个函数,而不是多线程的。如果直接调用run(),其实就相当于是调用了一个普通函数而已,直接调用run()方法必须等待run()方法执行完毕才能执行下面的代码,所以执行路径还是只有一条,根本就没有线程的特征,所以在多线程执行时要使用start()方法而不是run()方法。
2.实现Runnable接口(无返回值得任务必须实现Runnable接口,可返回值的任务必须实现Callable接口

public class Runnable_xc {
public static void main(String[] args) {
M1 m1 = new M1();
M2 m2 = new M2();
Thread t1 = new Thread(m1);
Thread t2 = new Thread(m2);
t1.start();
t2.start();
}
}
class M1 implements Runnable {
public void run() {
int i = 100;
while (i > 0) {
System.out.println(i--);
}
}
} class M2 implements Runnable {
public void run() {
int i = 100;
while (i > 0) {
System.out.println(i--);
}
}
}

以上两种方式在任务执行完成之后无法获取返回结果,如果就以上两种方法的话,推荐使用Runnable,简单的说就是因为单继承多实现

3.实现Callable接口通过FutureTask包装器来创建Thread线程(无返回值得任务必须实现Runnable接口,可返回值的任务必须实现Callable接口,重要的事情说2遍

Callable接口(也只有一个方法)定义如下:   泛型接口,call()函数返回的类型就是传递进来的V类型,Callable经常和java线程池一起启用:

public interface Callable<V>   {
V call() throws Exception; }
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask; public class MyCallable implements Callable<String> {     public String call() throws Exception {
        int i = 100;
        String rs = "false";
        while (i > 0) {
            System.out.println(i--);
            if (i == 50) {
                Thread.sleep(3000);
            }
            if (i == 1) {
                rs = "TRUE";
            }
        }
        return rs;
    }     public static void main(String[] args) {
        Callable<String> oneCallable0 = new MyCallable(); // 由Callable<String>创建一个FutureTask<String>对象:
        Callable<String> oneCallable1 = new MyCallable();
        FutureTask<String> oneTask0 = new FutureTask<String>(oneCallable0);
        FutureTask<String> oneTask1 = new FutureTask<String>(oneCallable1);         Thread oneThread0 = new Thread(oneTask0); // 由FutureTask<String>创建一个Thread对象:
        Thread oneThread1 = new Thread(oneTask1);         oneThread0.start();
        oneThread1.start();         try {
            System.out.println(oneTask0.get());
            System.out.println(oneTask1.get());//结果
        } catch (InterruptedException | ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } }

4.使用ExecutorService、Callable、Future

ExecutorService是一个线程池接口,执行Callable任务后,可以获取一个Future对象,在该对象上调用get就可以获取到Callable任务返回的Object,再结合ExecutorService接口就可以实现有返回结果的多线程

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; public class TH_POOL {
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 MyCallable3(i + " "); // 执行任务并获取Future对象
Future f = pool.submit(c);
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 MyCallable3 implements Callable<Object> {
private String taskNum; MyCallable3(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 + "毫秒】";
}
}

线程就先复习到这吧,手里还有点任务,表示并不想加班,所以没写那么细

java_多线程4种实现方式的更多相关文章

  1. python 多线程两种实现方式,Python多线程下的_strptime问题,

    python 多线程两种实现方式 原创 Linux操作系统 作者:杨奇龙 时间:2014-06-08 20:24:26  44021  0 目前python 提供了几种多线程实现方式 thread,t ...

  2. 【Python】python 多线程两种实现方式

    目前python 提供了几种多线程实现方式 thread,threading,multithreading ,其中thread模块比较底层,而threading模块是对thread做了一些包装,可以更 ...

  3. JAVA多线程三种实现方式

    JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...

  4. Java 多线程 三种实现方式

    Java多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...

  5. Java多线程--两种实现方式

    进程概述: 在这之前,有必要了解一下什么是进程? 在一个操作系统中,每个独立的执行的程序都可称为一个进程,也就是"正在运行的程序".如图所示: 线程概述: 如上所述,每个运行的程序 ...

  6. 【Java_多线程并发编程】基础篇—线程状态及实现多线程的两种方式

    1.Java多线程的概念 同一时间段内,位于同一处理器上多个已开启但未执行完毕的线程叫做多线程.他们通过轮寻获得CPU处理时间,从而在宏观上构成一种同时在执行的假象,实质上在任意时刻只有一个线程获得C ...

  7. Java多线程13:读写锁和两种同步方式的对比

    读写锁ReentrantReadWriteLock概述 大型网站中很重要的一块内容就是数据的读写,ReentrantLock虽然具有完全互斥排他的效果(即同一时间只有一个线程正在执行lock后面的任务 ...

  8. Java多线程的三种实现方式

    java多线程的三种实现方式 一.继承Thread类 二.实现Runnable接口 三.使用ExecutorService, Callable, Future 无论是通过继承Thread类还是实现Ru ...

  9. Java进阶(四十二)Java中多线程使用匿名内部类的方式进行创建3种方式

    Java中多线程使用匿名内部类的方式进行创建3种方式 package cn.edu.ujn.demo; // 匿名内部类的格式: public class ThreadDemo { public st ...

随机推荐

  1. Android权限管理知识学习记录

    一.Android权限背景知识 在Android 6.0之前,所申请的权限只需要在AndroidManifest.xml列举就可以了,从而容易导致一些安全隐患,因此,在Android 6.0时,Goo ...

  2. 【Core2.0帮助类】

    缓存帮助类(CacheHelper) /// <summary> /// 缓存帮助类 /// </summary> public class CacheHelper {//下载 ...

  3. weui 中的tabbar导航

    最近做微信的服务号项目,用的weui作为主要的ui,但是对于用惯了ele ui的开发者来说,文档貌似有点不友好.真是很让人头疼! 所以结合着自己做的项目,随便写一点东西. 比如说,tabbar导航的切 ...

  4. .net的retrofit--WebApiClient底层篇

    前言 本篇文章的内容是WebApiClient底层说明,也是WebApiClient系列接近尾声的一篇文章,如果你没有阅读过之前的的相关文章,可能会觉得本文章的内容断层,WebApiClient系列文 ...

  5. 项目架构开发:数据访问层之UnitOfWork (补充)

    应lisansi同学回复(项目架构开发:数据访问层之UnitOfWork)要求,补上Dapper的DbContext实现 using Dapper.Contrib.Extensions; using ...

  6. [ZOJ3256] Tour in the Castle

    插头DP+矩阵乘法 m喜闻乐见地达到了10^9级别..而n<=7,并且没有障碍..所以列与列之间的转移时一样的..就可以上矩乘了. 感觉自己快没救了..看半天题解还是不懂.. http://ww ...

  7. 2017ccpc哈尔滨区域赛H

    n堆石子 每次只能拿一个石子从一堆移到另一堆  知道所有的堆的石子数目都能整除x(x>1) 问最小移动次数 枚举x的可能取值  即a[i]和的素因子即可  合因子的区间变化会比较大   然后求余 ...

  8. c++(循环单向链表)

    前面的博客中,我们曾经有一篇专门讲到单向链表的内容.那么今天讨论的链表和上次讨论的链表有什么不同呢?重点就在这个"循环"上面.有了循环,意味着我们可以从任何一个链表节点开始工作,可 ...

  9. [OpenCV学习笔记3][图像的加载+修改+显示+保存]

    正式进入OpenCV学习了,前面开始的都是一些环境搭建和准备工作,对一些数据结构的认识主要是Mat类的认识: [1.学习目标] 图像的加载:imread() 图像的修改:cvtColor() 图像的显 ...

  10. Web前端:如何实现选择select下拉框选中跳转其他页面

    <select onchange="window.location=this.value;"><option value="a.html"&g ...