翻译自: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. AngularJS-03 过滤器

    过滤器 可以对输入的值按照指定的方案进行处理后再输出的函数. 1.货比过滤器currency:{{ currency_expression | currency : symbol}} 2.日期过滤器: ...

  2. Springboot整合MybatisPlus

    目录 1.pom文件 2.创建CodeGenerator.java 3.在application.yml中配置mybatis-plus 4.创建MybatisPlusConfig.java文件 其他 ...

  3. TimeUtil 工具类

    /** * TODO * * @auther xh * @date 6/11/19 3:32 PM */ public class TimeUtil { public static final Str ...

  4. excel中的更新链接

    表格每次打开都提示是否更新连接 在 [  数据 -->   编辑链接  ]  中也看到了这个连接 学着网上说的查找方式,去查找路径中包含的文字,文件名中包含的名字,都定位不到这个用了链接的单元格 ...

  5. NETGEAR路由器登录不上 重新获取ip

    当NETGEAR路由器更改了"局域网IP配置",或者重启之后,会出现登录不上的情况 释放IP地址 # ipconfig /release 重新获取 # ipconfig /rene ...

  6. 学习手写vue,理解原理

    class Compiler{ constructor(el,vm){ // 判断el属性 是不是 一个元素, 如果不是就获取 this.el = this.isElementNode(el)?el: ...

  7. 从Windows文件夹到Linux分区

    1. 先说几句 如果你, 知道什么是Windows系统 简单使用Windows系统 想要了解或安装Linux 刚接触Linux会有以下疑惑, 什么是分区? 如何建立分区? 怎么安装系统到到D盘? 安装 ...

  8. List.ForEach批量新增并发异常解决

    批量新增操作在业务系统中十分常见,尤其是主从表中对从表的批量处理.昨天在对wms主从表进行业务操作时使用了c#中list自带的函数ForEach对从表批量新增,代码如下: 在无并发的情况下接口请求正常 ...

  9. 01.CNN调参

    转载:调参是个头疼的事情,Yann LeCun.Yoshua Bengio和Geoffrey Hinton这些大牛为什么能够跳出各种牛逼的网络? 下面一些推荐的书和文章:调参资料总结Neural Ne ...

  10. IDEA设置CodeGlance颜色

    CodeGlance是IDEA的mini地图插件, 默认情况下, 其颜色和编辑框的颜色基本一致, 而安装CodeGlance就是为了方便滚动框的上下拖拉, 颜色一致的话会将这种CodeGlance比拖 ...