翻译自: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. select into from与insert into select区别

    创建一个table2  向table2中插入 table1中name为11的所有行(前提table2不存在) select * into table2 from table1 where name=‘ ...

  2. 电脑串口(com)被占用问题

    最近使用串口与设备通信. 这个电脑一个有6个COM口,都要使用. 还有自带一个华为的4G通信模块,这个模块需要虚拟出4个COM口. 使用之前的Gost系统(只有1个物理COM版本的),导致物理COM口 ...

  3. PHP如何通过URL访问,获得新的URL 两种方法

    1.1 $url = 'http://passport.drcloud.cn/api/logon.asp?id=1&ru=http://203.158.158.122/store/thirdL ...

  4. 使用 pdb 进行调试

    使用 pdb 进行调试 pdb 是 python 自带的一个包,为 python 程序提供了一种交互的源代码调试功能,主要特性包括设置断点.单步调试.进入函数调试.查看当前代码.查看栈片段.动态改变变 ...

  5. JavaScript 标准内置对象

    JavaScript 标准内置对象或称全局的对象(global objects)不要和 全局对象(global object)混淆.这里说的全局的对象是说在全局作用域里的对象,全局作用域包含了全局对象 ...

  6. 解决织梦5.7添加新变量出现:Request var not allow!的办法

    找到:根目录->include->common.inc.phpif( strlen($svar)>0 && preg_match('#^(cfg_|GLOBALS|_ ...

  7. 玩转springcloud(三):服务的提供者与调用者(注册于发现)

    一.简介 上文我们实践了cloud的注册中心的单服务于多节点的搭建,房子造好了得有人来住不是,这篇我们实践下服务提供者于调用者的案例,也就是服务端和客户端的调用. 本文会设计三个module:注册中心 ...

  8. matlab FDA

    FDA是filter design analysis过滤器设计与分析的缩写.

  9. 计算机基础与python入门

    一.计算机.cpu与存储器 二.操作系统.编程语言及编写python.变量 三.数据类型.输入输出及基本运算 四.流程控制之if判断.while与for循环 一.计算机.cpu与存储器 1. 什么是编 ...

  10. SpringCloud01——服务的注册和发现

    SpringCloud01--服务的注册和发现 一.微服务的注册和发现 我们在微服务中,往往有服务提供者,服务消费者和服务注册中心.我们之前学习的Zookeeper就是一个注册中心.但是在官方的Spr ...