Java实现线程的两种方法

  • 继承Thread类
  • 实现Runnable接口

它们之间的区别如下:

1)Java的类为单继承,但可以实现多个接口,因此Runnable可能在某些场景比Thread更适用
2)Thread实现了Runnable接口,并且有更多实用方法
3)实现Runnable接口的线程启动时仍然需要依赖Thread或者java.util.concurrent.ExecutorService

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import org.junit.Assert;
import org.junit.Test; /**
* @Description: 线程的两种实现方法
*/
public class ThreadImplementTest {
private Map<Integer, Long> map = new ConcurrentHashMap<>(); class MethodOne extends Thread {
private int count = 0; @Override
public void run() {
map.put(++count, this.getId());
}
} class MethodTwo implements Runnable {
private int count = 0; @Override
public void run() {
map.put(++count, Thread.currentThread().getId());
}
} @Test
public void textThread() {
/**
* 方法一:继承Thread
*/
MethodOne extendsThread = new MethodOne();
extendsThread.start();
/**
* 方法二:实现Runnable
*/
MethodTwo implementsRunnable = new MethodTwo();
new Thread(implementsRunnable).start();
} @Test
public void testTwoRuns() throws InterruptedException {
/**
* 注意:以下两种方法启动方式截然不同
*/
Thread tmp;
MethodOne extendsThread = new MethodOne();
for (int i = 0; i < 3; i++) {// 只有一个线程
tmp = new Thread(extendsThread);
tmp.start();
tmp.join();
}
Assert.assertTrue(map.containsKey(3));
Assert.assertTrue(map.containsKey(2));
Assert.assertTrue(map.containsKey(1)); map.clear();// 清空缓存
for (int i = 0; i < 3; i++) {// 三个不同线程
tmp = new MethodOne();
tmp.start();
tmp.join();
}
Assert.assertEquals(1, map.size());
Assert.assertTrue(map.containsKey(1));
}
}

Java多线程系列一——Java实现线程方法的更多相关文章

  1. 【Java多线程系列三】实现线程同步的方法

    两种实现线程同步的方法 方法 特性 synchronized  不需要显式的加锁,易实现 ReentrantLock 需要显式地加解锁,灵活性更好,性能更优秀,结合Condition可实现多种条件锁  ...

  2. Java多线程系列 基础篇02 线程的创建和运行

    1.线程创建的方式常用有两种 1. 继承 Thread 类创建线程 2. 实现 Runnable 接口创建线程 2.Thread 和 Runnable的区别 Thread和Runnable的相同点:都 ...

  3. Java多线程系列 基础篇03 线程的优先级和守护线程

    1. 线程优先级 现代操作系统中基本上使用时间分片的方式调度线程,通过设置线程优先级,使优先级高的线程获得时间片的次数多于优先级低的线程. 在java 线程中,通过一个整形变量prority来控制优先 ...

  4. Java多线程系列二——Thread类的方法

    Thread实现Runnable接口并实现了大量实用的方法 public static native void yield(); 此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将可能得到执行机 ...

  5. 【java多线程系列】java内存模型与指令重排序

    在多线程编程中,需要处理两个最核心的问题,线程之间如何通信及线程之间如何同步,线程之间通信指的是线程之间通过何种机制交换信息,同步指的是如何控制不同线程之间操作发生的相对顺序.很多读者可能会说这还不简 ...

  6. java多线程系列5-死锁与线程间通信

    这篇文章介绍java死锁机制和线程间通信 死锁 死锁:两个或两个以上的线程在争夺资源的过程中,发生的一种相互等待的现象. 同步代码块的嵌套案例 public class MyLock { // 创建两 ...

  7. Java多线程系列 基础篇01 线程的状态

    1.进程和线程 进程: 计算机中程序关于某数据集合的一次运行活动,是计算机系统进行资源分配和调度的基本单位,是操作系统结构的基础. 线程: 线程是进程的实例,是CPU进行资源分配和调度的最小单位,线程 ...

  8. 【Java多线程系列四】控制线程执行顺序

    假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...

  9. (Java多线程系列五)守护线程

    守护线程 什么是守护线程 Java中有两种线程,一种是用户线程,一种是守护线程. 当进程不存在或主线程停止,守护线程也会自动停止. class DaemonThread extends Thread ...

随机推荐

  1. cookie、localStorage和sessionStorage三者的异同

    1.三者都是用来存储浏览器数据的 2.生命周期:cookie可以设置数据失效时间,默认是关闭浏览器后失效:localStorage中的数据是永久保存的,除非手动清除:sessionStorage的数据 ...

  2. [luoguP1013] 进制位(搜索)

    传送门 纯搜索,无优化! #include <cstdio> #include <cstring> #include <iostream> #include < ...

  3. bzoj 2223 [Coci 2009]PATULJCI

    [Coci 2009]PATULJCI Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1286  Solved: 553[Submit][Status ...

  4. idea导入(import)项目和打开(open)项目的区别

    前言: 每次接手老项目,都得从git或svn下载下来,但是如果之前的项目不是用idea写的怎么办,可是你又习惯啦idea,那你必须把项目在idea上跑起来,那是用import还是用open呢,如何抉择 ...

  5. 姓名与ID(codevs 1027 未结题)

    题目描述 Description 有N个人,各自有一个姓名和ID(别名).每个人的姓名和ID都没有重复.这些人依次进入一间房间,然后可能会离开.过程中可以得到一些信息,告知在房间里的某个人的ID.你的 ...

  6. Linux下汇编语言学习笔记63 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  7. HDU 1754_I Hate It

    [题意]给定区间求最大值 [分析]线段树单点更新 [代码] #include<cstdio> #include<iostream> using namespace std; c ...

  8. Ubuntu 16.04安装RabbitVCS替代TortoiseSVN/TortoiseGit

    RabbitVCS官网:http://www.rabbitvcs.org/easonjim 1.添加PPA源 sudo add-apt-repository ppa:rabbitvcs/ppa 如果导 ...

  9. redis 主从 及集群

    一.redis 主从架构 搭建redis 主从   (可以用一台主机,也可以两台主机) 环境准备: 一台服务器:192.168.206.6 操作系统:CentOS7.5 redis 版本: redis ...

  10. String类的四个默认成员函数

    优化版的拷贝构造函数,先创建一个暂时实例tmp,接着把tmp._ptr和this->_ptr交换,因为tmp是一个局部变量.程序执行到该函数作用域外,就会自己主动调用析构函数.释放tmp._pt ...