一、什么是线程?

线程:程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位。

多线程:单个程序中同时运行多个线程完成不同的工作,称为多线程。

特点:

1)轻量级的进程,程序运行流中可执行的最小单元,线程不拥有系统资源,多个线程共享进程拥有的资源。

2)一个线程可以创建另外一个线程,多个线程可以并发执行。

3)多个线程在系统运行中抢占资源,会出现间断性,我们看到的是并行执行,其实在有先后顺序的。

4)一个进程至少包含一个线程,即主线程。

二、线程有哪些状态?

 

 

线程具有:新建,就绪,运行,阻塞,终止五种状态。

①新建:线程被创建,没有执行任何方法,如,Thread th = new Thread()。

②就绪:当调用线程的start方法时,就会触发线程状态变更为就绪态,等待cpu来调用。处于就绪态的线程才会被cpu调度,单cpu不是立即执行它。

③运行:当cpu发起对此线程调用时,它就进入了运行态。

④阻塞:当线程由于某种原因,不再拥有cpu使用权,它就会被阻塞。

阻塞有以下几种情况:

1)sleep(long mills):参数为毫秒数,使线程在指定的时间内进入阻塞,时间一过,进入就绪态。

2)suspend() 和 resume():suspend会让线程挂起,必须执行resume进行线程的恢复。

3)yield():与sleep()类似,但是不能由用户指定暂停多长时间,只能出让机会给同优先级的线程,且不进入阻塞。如同排队,前面的人和后面的人交换位置,但是还处在队伍中。

4)wait() 和 notify():wait() 使线程进入阻塞状态,有两种形式,一种指定毫秒数,另一种无参。前者可通过notify()唤起或者超过指定时间自动恢复;后者必须通过notify()唤起。

5)同步阻塞:等待同步锁资源。多线程竞争同一个资源时,只能一个线程获得锁,其它的线程要等待。

⑤终止:线程执行完毕,或者出现异常,线程结束。

三、如何创建线程?

java线程的实现方式有三种:继承Thread类、实现Runnable接口,使用Callable和FutureTask(可以有返回值)

1、通过集成Thread类,覆写run()方法

class MyThread extends Thread {

@Override

public void run() {

for (int i = 0; i < 10; i++) {

System.out.println(Thread.currentThread().getName() + " " + i);

}

}

}

public class ThreadDemo {

public static void main(String[] args) {

System.out.println(Thread.currentThread().getName());

MyThread th1 = new MyThread();

MyThread th2 = new MyThread();

th1.start();

th2.start();

}

}

输出:main

Thread-1 0

Thread-0 0

Thread-1 1

Thread-1 2

......

线程要实现的逻辑写在run方法中,通过执行线程的start()方法,使线程进入就绪状态,等待CPU分配资源。

可以看到两个线程并行执行,且随机获得CPU。

2、试过实现Runnable接口,实现run()方法

class MyThread implements Runnable {

@Override

public void run() {

for (int i = 0; i < 10; i++) {

System.out.println(Thread.currentThread().getName() + " " + i);

}

}

}

public class ThreadDemo {

public static void main(String[] args) {

System.out.println(Thread.currentThread().getName());

MyThread th = new MyThread();

Thread t1 = new Thread(th);

Thread t2 = new Thread(th);

t1.start();

t2.start();

}

}

输出:main

Thread-0 0

Thread-0 1

Thread-1 0

Thread-0 2

......

通过将MyThread实例传入Thread构造方法实例化Thread,调用Thread的start方法,启动线程。

ps:继承Thread和实现Runnable接口有什么区别呢?

1:前者为单继承,有局限性,但接口的方式可以实现多个。

2:后者可以实现资源共享。

多线程编程中,强烈建议使用Runnable

3、使用Callable和Future接口创建线程。

具体是创建Callable接口的实现类,并实现clall()方法。

并使用FutureTask类来包装Callable实现类的对象,且以此FutureTask对象作为Thread对象的target来创建线程。

class MyCallable implements Callable<Integer> {

@Override

public Integer call() throws Exception {

return 1;

}

}

public class ThreadDemo {

public static void main(String[] args)  {

Callable<Integer> myCallable = new MyCallable();//实例化MyCallable

FutureTask<Integer> ft = new FutureTask<>(myCallable);//通FutureTask包装

Thread thread = new Thread(ft);//将FutureTask传入Thread构造,实例化线程

thread.start();//线程启动

Integer result = ft.get();//获取返回值

System.out.println(result);

}

}

1)实现Callable接口中的call()方法,这个是线程要执行的逻辑。

2)FutureTask的get()方法会一直阻塞,直到call()方法执行完毕取到返回值。

关注老姜谈技术,微信号:helojava,或者扫描下面二维码。


每日一帖,技术鸡汤。

java多线程实现方式的更多相关文章

  1. 夯实Java基础系列17:一文搞懂Java多线程使用方式、实现原理以及常见面试题

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  2. Java 多线程实现方式三:实现 Callable 接口

    完整套路 java 通过实现Callable 接口来实现多线程相比较于继承Thread 接口和 实现Runnable 接口比较麻烦,但好处是可以有返回值. 基本套路: 1. 创建目标对象 2. 创建执 ...

  3. Java 多线程实现方式二:实现 Runnable 接口

    由于java是单继承,很多时候为了实现多线程 通过继承 Thread 类后,就不能再继承其他类了.为了方便可以通过实现 Runnable 接口来实现,和Tread 类似需要重写run 方法. 下面通过 ...

  4. Java 多线程实现方式一:继承Thread类

    java 通过继承Thread类实现多线程很多简单: 只需要重写run方法即可. 比如我们分三个线程去京东下载三张图片: 1.先写个下载类: 注意导入CommonsIO 包 public class ...

  5. JAVA多线程实现的四种方式

    Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorService.Cal ...

  6. JAVA多线程实现的三种方式

    JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...

  7. JAVA多线程实现的两种方式

    java多线程实现方式主要有两种:继承Thread类.实现Runnable接口 1.继承Thread类实现多线程 继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了 ...

  8. 【转】JAVA多线程实现的四种方式

    原文地址:http://www.cnblogs.com/felixzh/p/6036074.html Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callabl ...

  9. JAVA多线程实现的四种方式(转自https://www.cnblogs.com/felixzh/p/6036074.html)

    Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorService.Cal ...

随机推荐

  1. 利用for循环找出1000以内的质数

    var n=0; for(var i=2;i<=1000;i++){  var zhishu=true;  for(var j=2;j<i;j++){    if(i%j==0){    ...

  2. Node.js入门

    开始之前,安利一本正在看的书<站在两个世界的边缘>,作者程浩,上帝丢给他太多理想,却忘了给他完成理想的时间.OK,有兴趣的可以看一看. node.js如标题一样,我也是刚开始接触,大家一起 ...

  3. css_02之盒模型、渐变

    1.框模型:盒模型,①对象实际宽度=左右外边距+左右边框+左右内边距 + width:②对象实际高度=上下外边距+上下边框+上下内边距 + height: 2.外边距:margin:取值:①top(上 ...

  4. VS2015墙内创建ionic2 【利用nrm更换源,完美!】

    STEP 1 设置cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org   一句话建立cnpm STEP 2 安装nr ...

  5. A/B Testing的简要知识

    A/B testing主要用来检测网站或者APP的两个版本中哪一个更好,它的中心思想是把流量一分为二,一份用作experiment group,访问新的版本,另一份用作control group,访问 ...

  6. 虚拟机VMware12.05下安装Ubuntu16.04几个关键地方

    在踩了自己按照网上的教程安装Ubuntu之后,仍然踩了不少坑,鼓捣了一段时间,才达到自己想要的界面.   下面就来说说,大家可能也会遇到的情况:   1.安装ISO镜像时候,路径直接选择 你从Ubun ...

  7. 二叉树的创建和遍历(C版和java版)

    以这颗树为例:#表示空节点前序遍历(根->左->右)为:ABD##E##C#F## 中序遍历(左->根->右)为:#D#B#E#A#C#F# 后序遍历(左->右-> ...

  8. Struts2框架基础

    Struts2框架基础 1.Java的框架 1.1.框架简介 在大型项目开发过程中,经常会使用到一些框架,这样做好的好处是能够提高工作效率,在java中最常用的的框架就是SSH,这其实是三个框架的简称 ...

  9. 腾讯云 安装mono

    一.yum -y update 运行出现以下错误: http://centos.tencentyun.com/contrib/x86_64/repodata/filelists.xml.gz: [Er ...

  10. GO 基础(一)

    Go语言基础工程目录如下(采用LiteIDE): 备注:需要提前设置GOPATH,即工作目录,bin.pkg.src为默认的GO工程目录结构.GOPATH可以支持多个,在windows下配置在环境变量 ...