翻译自:https://www.journaldev.com/1016/java-thread-example

进程

进程是一个自包含的执行环境,它可以被看成一个程序或应用程序。然而一个应用程序本身包含多个进程,Java运行时环境作为一个单独的进程运行,它包含不同的类和程序

线程

线程可以成为轻量级进程,一个进程包含很多线程,线程占用很少的资源在进程中创建和运行,线程共享进程的资源

每个应用程序至少包含一个线程——主线程(main thread)。尽管有很多其他的java线程在后台运行,比如内存管理、系统管理、信号处理等等。但是从应用程序的角度来看——主线程是第一个java线程,我们可以从主线程中创建多个线程。

多线程是指在单个程序中同时执行的两个或多个线程。一个计算机单核处理器只能一次执行一个线程,而时间切片是在不同进程和线程之间共享处理器时间的操作系统特性。

Java线程的好处

  1. 与进程相比,Java线程是轻量级的,创建线程需要更少的时间和资源。
  2. 线程共享其父进程数据和代码,线程之间的上下文切换通常比进程之间的开销要小,线程间通信相对于进程通信来说是相对容易的
  3. Java提供了两种以编程方式创建线程的方法,实现java.lang.Runnable接口或继承java.lang.Thread类

线程实例

Java 线程 – 实现Runnable接口

为了使类可运行,我们可以实现java.lang。Runnable接口,并在public void.run()方法中提供实现。要将这个类用作线程,我们需要通过传递这个runnable类的对象创建一个线程对象,然后调用start()方法在一个单独的线程中执行run()方法

下面是一个实现Runnable接口的java线程示例:

package com.lkf.mulithread;

public class WorkRunnable implements Runnable {
@Override
public void run() {
System.out.println("Doing WorkRunnable processing - START " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
doSomething();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Doing WorkRunnable processing - END " + Thread.currentThread().getName());
} private void doSomething() throws InterruptedException {
System.out.println("WorkRunnable do something");
Thread.sleep(2000);
System.out.println("WorkRunnable sleep 2000 millis");
}
}

Java 线程 – 继承 Thread 类

我们可以继承 java.lang.Thread 类创建我们自己的线程类并且覆盖 run() 方法。然后我们可以创建它的对象并调用 start() 方法,启动线程执行我们自定义的方法

下面是继承 Thread 类创建线程的实例:

package com.lkf.mulithread;

public class WorkExtendThread extends Thread {
public WorkExtendThread(String name) {
super(name);
} @Override
public void run() {
System.out.println("WorkExtendThread - START " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
doSomething();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("WorkExtendThread - END " + Thread.currentThread().getName());
} private void doSomething() throws InterruptedException {
System.out.println("WorkRunnable do something");
Thread.sleep(2000);
System.out.println("WorkRunnable sleep 2000 millis");
}
}

下面是一个展示如何创建java线程并执行它的测试程序:

package com.lkf.mulithread;

public class ThreadRunExample {
public static void main(String[] args) {
Thread implRunnableThread1 = new Thread(new WorkRunnable(), "ImplRunnableThread1");
Thread implRunnableThread2 = new Thread(new WorkRunnable(), "ImplRunnableThread2");
System.out.println("Starting ImplRunnableThread threads");
implRunnableThread1.start();
implRunnableThread2.start();
System.out.println("Runnable ImplRunnableThread has been started"); Thread workExtendThread3 = new WorkExtendThread("WorkExtendThread3");
Thread workExtendThread4 = new WorkExtendThread("WorkExtendThread4");
System.out.println("ExtendThreads MyThreads");
workExtendThread3.start();
workExtendThread4.start();
System.out.println("ExtendThreads has been started"); }
}

运行结果如下:

Starting ImplRunnableThread threads
Doing WorkRunnable processing - START ImplRunnableThread1
Doing WorkRunnable processing - START ImplRunnableThread2
Runnable ImplRunnableThread has been started
ExtendThreads MyThreads
WorkExtendThread - START WorkExtendThread3
WorkExtendThread - START WorkExtendThread4
ExtendThreads has been started
WorkRunnable do something
WorkExtendThread do something
WorkExtendThread do something
WorkRunnable do something
WorkRunnable sleep 2000 millis
WorkExtendThread sleep 2000 millis
Doing WorkRunnable processing - END ImplRunnableThread1
WorkExtendThread - END WorkExtendThread4
WorkRunnable sleep 2000 millis
WorkExtendThread sleep 2000 millis
Doing WorkRunnable processing - END ImplRunnableThread2
WorkExtendThread - END WorkExtendThread3

一旦我们启动了任何线程,它的执行依赖于时间切片的OS实现,我们无法控制它们的执行。但是,我们可以设置线程优先级,但即使这样,它也不能保证优先执行更高的优先级线程。

Runnable vs Thread

如果您的类提供了更多的功能,而不是仅仅作为线程运行,那么您应该实现Runnable接口,以提供一种将其作为线程运行的方法。 如果你只是希望创建一个可执行的线程,则可以继承Thread类。

实现Runnable是首选,因为java支持实现多个接口。如果继承Thread类,则不能继承其他类。

提示:您已经注意到,线程没有返回任何值,但是如果我们希望我们的线程执行一些处理,然后将结果返回给我们的客户端程序,那我们可以使用Java Callable Future,后面会另起篇幅说明。

更新:从Java 8开始,Runnable是一个功能接口,我们可以使用lambda表达式来提供它的实现,而不是使用匿名类。有关更多细节,将在使用Java 8功能接口中说明。

Java线程之创建线程的更多相关文章

  1. Java中如何创建线程

    Java中如何创建线程 两种方式:1)继承Thread类:2)实现Runnable接口. 1.继承Thread类 继承Thread类,重写run方法,在run方法中定义需要执行的任务. class M ...

  2. Java并发--如何创建线程

    下面是本文的目录大纲: 一.Java中关于应用程序和进程相关的概念 二.Java中如何创建线程 三.Java中如何创建进程 转载原文链接:http://www.cnblogs.com/dolphin0 ...

  3. java的线程、创建线程的 3 种方式、静态代理模式、Lambda表达式简化线程

    0.介绍 线程:多个任务同时进行,看似多任务同时进行,但实际上一个时间点上我们大脑还是只在做一件事情.程序也是如此,除非多核cpu,不然一个cpu里,在一个时间点里还是只在做一件事,不过速度很快的切换 ...

  4. java学习之创建线程方法二

    我们上一节当中讲到了创建线程的第一种方法,就是继承Thread类,覆写Thread当中的run方法,然后创建子类对象,之后调用对象的start方法启动线程.但是这种方法有一个缺陷,因为我们知道在jav ...

  5. Java多线程-----匿名内部类创建线程

       1.继承Thread类创建线程 package com.practise.createthread; public class AnonymousThread { public static v ...

  6. Java多线程——之一创建线程的四种方法

    1.实现Runnable接口,重载run(),无返回值 package thread; public class ThreadRunnable implements Runnable { public ...

  7. Java多线程之创建线程的三种方式比较

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6560057.html  一:继承Thread类创建线程 1:继承Thread类定义线程子类: 2:重写run( ...

  8. java核心知识点----创建线程的第三种方式 Callable 和 Future CompletionService

    前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的. Call ...

  9. java 多线程 day01 创建线程

    线程,即代码的执行路径java 面向对象编程.所以线程在java中也是用对象来表示的,创建线程对象的类就是 Thread如下代码即开启一个新的线程,通过线程对象的start方法,即可启动线程 Thre ...

  10. java多线程之创建线程的4种方式及Future

    Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例.Java可以用四种方式来创建线程: 继承Thread创建线程 实现Runnable接口创建线程 实现callab ...

随机推荐

  1. AOP与IOC区别

    Spring核心知识 Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson在其著作Expert One-On-One J2EE Devel ...

  2. Spring在Thread中注入Bean无效的解决方式

    在Spring项目中,有时需要新开线程完成一些复杂任务,而线程中可能需要注入一些服务.而通过Spring注入来管理和使用服务是较为合理的方式.但是若直接在Thread子类中通过注解方式注入Bean是无 ...

  3. SQLException: #22001你知道这个错误码吗

    做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! java.sql.SQLException: #22001 java.sql.SQLException: #22001 a ...

  4. php对象转换为数组的部分代码

    function object_array($array){ if(is_object($array)){ $array = (array)$array; } if(is_array($array)) ...

  5. String Class

    #include <iostream> #include <fstream> #include <sstream> using namespace std; tem ...

  6. SpringBoot-JPA入门

    SpringBoot-JPA入门 JPA就是Spring集成了hibernate感觉. 注解,方法仓库(顾名思义的方法,封装好了,还有自定义的方法). 案例: spring: datasource: ...

  7. Flutter 35: 图解自定义 View 之 Canvas (二)

    小菜前几天整理了以下 Canvas 的部分方法,今天小菜继续学习 Canvas 第二部分. drawXXX drawShadow 绘制阴影 drawShadow 用于绘制阴影,第一个参数时绘制一个图形 ...

  8. 如何在调用Marketing Cloud contact创建API时增加对扩展字段的支持

    需求:扩展字段"微信ID"是我创建出来的extension field,我想用Marketing Cloud提供的contact creation API,在创建contact时也 ...

  9. 为何一线城市的企业更愿意选择 Spring Cloud?

    最近公司正在搭建微服务框架,处于小白的我,赶紧借书,上网,实操的学习了一下,下面是一些自己的入门的总结: 目录: 一.怎么理解Spring Cloud? 一.Spring Cloud 的优势在哪? 一 ...

  10. 第三章、Django之路由层

    目录 第三章.Django之路由层 一 路由的作用 二 简单的路由配置 三 分组 四 路由分发 五 反向解析 六 名称空间 七 django2.0版的re_path与path 第三章.Django之路 ...