java多线程(一)-五种线程创建方式

简单使用示例

Java 提供了三种创建线程的方法:

  • 通过实现 Runnable 接口;
  • 通过继承 Thread 类本身;
  • 通过 Callable 和 Future 创建线程。

还有

  • 定时器
  • 线程池

下面第一个类给出了四种创建方式,第二个类是定时器示例。

public class ThreadStartTest {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.print("主线程(main)0启动!");

        //实例化线程对象
        Thread_1 thread_1 = new Thread_1();
        //调用start()方法开启线程,然后会自动调用run()方法
        thread_1.start();

        //将实现Runnable接口对象实例化提交给Thread构造器(构造方法)
        Thread thread_2 = new Thread(new Thread_2());
        thread_2.start();

        //callable接口可以返回值,但必须用submit()提交
        ExecutorService execu = Executors.newCachedThreadPool();
        Future<String> result  = execu.submit(new TastWithResult());
        System.out.println(result.get());
        execu.shutdown();

        //线程池
        ExecutorService exec = Executors.newCachedThreadPool();
        exec.execute(new Thread_2());
        exec.shutdown();

        //main线程
        for(int i=0;i<5;i++) {
            //等同于Thread.sleep(2000);
            TimeUnit.MILLISECONDS.sleep(2000);
            System.out.print("0");
        }
    }
}
/**
 *  继承Thread类,重写run方法
 */
class Thread_1 extends Thread {
    @Override
    public void run() {
        System.out.print("线程1启动!");
        for(int i=0;i<5;i++) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.print("1");
        }
    }
}

/**
 * 实现Runnable接口
 */
class Thread_2 implements Runnable{
    @Override
    public void run() {
        System.out.print("线程2启动!");
        for(int i=0;i<5;i++) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.print("2");
        }
    }
}

class TastWithResult implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "可以返回值啦!";
    }
}

②定时器Timer

public class TimerTest {

    public static void main(String[] args) throws InterruptedException {
        Timer timer = new Timer();

        //前一次执行程序结束后 2000ms 后开始执行下一次程序(循环)
        timer.schedule(new TimerTask(){
            @Override
            public void run(){
                System.out.println("Task1");
            }
        },0,2000);
        //延迟1000ms执行程序
        timer.schedule(new TimerTask(){
            @Override
            public void run(){
                System.out.println("Task2");
            }
        },1000);
        //前一次程序执行开始 后 2000ms后开始执行下一次程序(循环)
        timer.scheduleAtFixedRate(new TimerTask(){
            @Override
            public void run(){
                System.out.println("Task3");
            }
        },0,2000);
        Thread.sleep(10*1000);
        timer.cancel();
    }
}

如果你想详细的了解一下Timer内部实现,可以参考下面的文章

Time类的使用和源码分析-小淘气儿

说明

在《阿里巴巴java开发手册中》有这样一条:

3. 【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。

说明:使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或

者“过度切换”的问题。

所以建议使用线程池。

4. 【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样
的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors 返回的线程池对象的弊端如下:
1)FixedThreadPool 和 SingleThreadPool:
允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
2)CachedThreadPool 和 ScheduledThreadPool:
允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

又因为有该建议,所以需要对线程池稍微深入了解使用。可以参考下面这篇文章。

Java并发编程:线程池的使用-海子

原文地址:https://www.cnblogs.com/lifan1998/p/10351902.html

时间: 2024-09-30 10:11:18

java多线程(一)-五种线程创建方式的相关文章

java多线程总结五:线程池的原理及实现

1.线程池简介:     多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.        假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间.    如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能.                 一个线程池包括以下四个基本组成部分:                 1.线程池管理器(ThreadPool):用于创建并管

Java中String两种不同创建方式的区别及intern的用法

一, Java有两种创建字符串的方式, String str1 = "abc"; String str2 = new String("abc"); 用双引号创建和用new来创建.这两种方式创建出来的String存储的位置上不同的.当使用双引号方式时,相当于显式的声明了字符串的值(字面值),所以是作为一个常量,存储在方法区的常量池中.使用new方式来创建String时,JVM会在堆上分配一块区域,存储一个String对象,值为“abc”. 二, String的==和e

Java多线程的五种状态

新建状态:new Thread(参数)之后,建立了一个线程对象; 就绪状态:线程对象建立之后,调用start()方法,进入就绪状态,此时并不会直接调用run()方法,线程进入运行状态还需要抢占CPU资源才可以: 运行状态:线程抢到CPU资源后开始执行run()方法,就进入了运行状态: 阻塞状态:当线程遇到一些情况时,会暂时退出CPU资源,让其他线程先执行,此时就进入了线程阻塞状态: 线程阻塞的情况:1.睡眠,2等待被唤醒,3,当该线程试图得到一个锁,该锁正在被其他线程占用:4.调用I/O阻塞操作

【Java多线程】两种基本实现框架

Java多线程学习1——两种基本实现框架 一.前言 当一个Java程序启动的时候,一个线程就立刻启动,改程序通常也被我们称作程序的主线程.其他所有的子线程都是由主线程产生的.主线程是程序开始就执行的,并且程序最终是以主线程的结束而结束的. Java编写程序都运行在在Java虚拟机(JVM)中,在JVM的内部,程序的多任务是通过线程来实现的.每用Java命令启动一个Java应用程序,就会启动一个JVM进程.在同一个JVM进程中,有且只有一个进程,就是它自己.在这个JVM环境中,所有程序代码的运行都

Java多线程之 -- 进程和线程

Java多线程之 – 进程和线程 概念 进程 程序的动态执行过程 包括占用的资源(内存.CPU)和线程 线程 线程是程序中最小的执行单位 一个进程有多个线程 线程共享进程的资源 进程和线程的区分 我们可以想象为进程为班级而线程是邦奇中得每一个学生 线程之间的交互 互斥,类似于每一个学生都为了第一名而你争我让,线程也是,都想抢占CPU的资源 同步,当举行运动会的时候,大家都团结一心,彼此共享自己的资源 Thread.Runnable Thread Introduction Thread 是Java

Java中的五种单例模式实现方法

[代码] Java中的五种单例模式实现方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 package s

Java多线程编程基础之线程对象

在进入java平台的线程对象之前,基于基础篇(一)的一些问题,我先插入两个基本概念. [线程的并发与并行] 在单CPU系统中,系统调度在某一时刻只能让一个线程运行,虽然这种调试机制有多种形式(大多数是时间片轮巡为主),但无论如何,要通过不断切换需要运行的线程让其运行的方式就叫并发(concurrent).而在多CPU系统中,可以让两个以上的线程同时运行,这种可以同时让两个以上线程同时运行的方式叫做并行(parallel). 在上面包括以后的所有论述中,请各位朋友谅解,我无法用最准确的词语来定义储

Java多线程(五)、多线程其他知识简要介绍(转)

Java多线程(五).多线程其他知识简要介绍 分类: javaSE综合知识点 2012-09-19 18:12 1413人阅读 评论(1) 收藏 举报 一.线程组 [java] view plaincopyprint? /** * A thread group represents a set of threads. In addition, a thread * group can also include other thread groups. The thread groups form

Java 多线程(八) 线程状态图

结合多线程的学习过程,介绍线程的状态图,随着学习的深入,这幅图不断加入新的内容. 一.线程基本状态图 这幅图是在Java 多线程(三) 线程的生命周期及优先级出现过的: 图中是线程运行的基本状态:线程调用start()方法开始后,就进入到可运行状态,随着CPU的资源调度在运行和可运行之间切换:遇到阻塞则进入阻塞状态. 二.加入同步的线程状态图 多线程的同步机制,及synchronized关键字的使用学习: Java 多线程(五) 多线程的同步 Java 多线程(六) synchronized关键