目录:

  多线程的实现方法:

    继承Thread类

    实现Runnable接口

  -------------------------------------------------------------------------------------

  1. 继承Thread类

    继承Thread类之后,需要覆盖父类的 public void run() 方法,作为线程的主方法。

    所有线程的执行一定是并发的,即:同一个时间段上会有多个线程交替执行。为了达到这样的目的,绝对不能直接调用run()方法,而是应该调用Thread类的start()方法启动多线程。

    调用 start() 方法和调用 run() 方法的对比:

public class MyThread extends Thread {
private String name;
public MyThread(String name) {
this.name = name;
} @Override
public void run() {
for(int i=0; i<10; i++) {
System.out.println(name + "打印:" + i);
}
} public static void main(String[] args) {
MyThread mt1 = new MyThread("线程A");
MyThread mt2 = new MyThread("线程B");
MyThread mt3 = new MyThread("线程C");
mt1.start();
mt2.start();
mt3.start();
}
}

  运行结果:(三个线程同时且交替执行,没有固定的执行顺序)

   

public class MyThread extends Thread {
private String name;
public MyThread(String name) {
this.name = name;
} @Override
public void run() {
for(int i=0; i<5; i++) {
System.out.println(name + "打印:" + i);
}
} public static void main(String[] args) {
MyThread mt1 = new MyThread("线程A");
MyThread mt2 = new MyThread("线程B");
MyThread mt3 = new MyThread("线程C");
mt1.run();
mt2.run();
mt3.run();
}
}

  运行结果:(三个程序依次顺序执行)

   

  2. start()方法实现多线程的原理

    打开Thread类源代码中start()方法的部分:

public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}
private native void start0();

    native关键字是指调用操作系统的方法,start0()方法是所在操作系统的方法。

    由于线程的启动需要牵扯到操作系统中资源的分配问题,所以具体的线程的启动应该根据不同的操作系统有不同的实现。而JVM根据不同的操作系统中定义的start0()方法进行不同的实现。这样,在多线程的层次上start0()方法的名称不改变,而不同的操作系统有不同的实现。

原理图

    结论:只有Thread类的start()方法才能进行操作系统资源的分配,所以启动多线程的方式永远就是Thread类的start()方法。

  3. 实现Runnable接口

    一般使用这种方式来实现多线程,因为这样可以避免继承Thread类的单继承局限

package test;

public class MyThread implements Runnable {
private String name;
public MyThread(String name) {
this.name = name;
} @Override
public void run() {
for(int i=0; i<5; i++) {
System.out.println(name + "打印:" + i);
}
} public static void main(String[] args) {
MyThread mt1 = new MyThread("线程A");
MyThread mt2 = new MyThread("线程B");
MyThread mt3 = new MyThread("线程C");
new Thread(mt1).start();
new Thread(mt2).start();
new Thread(mt3).start();
}
}

  4. Thread类 与 Runnable接口 的联系与区别

    联系

      Thread类是实现了Runnable接口的类。

      

    区别

      Runnable接口实现的多线程要比Thread类实现的多线程更方便的表示出数据共享的概念。

      范例:希望有三个线程进行卖票

//使用Thread类实现

public class MyThread extends Thread {
private String name;
int tickets = 5; public MyThread(String name) {
this.name = name;
} @Override
public void run() {
while(tickets>0) {
System.out.println(name + "买票出一张票,剩余票数:" + (--tickets));
}
} public static void main(String[] args) {
MyThread mt1 = new MyThread("线程A");
MyThread mt2 = new MyThread("线程B");
MyThread mt3 = new MyThread("线程C");
mt1.start();
mt2.start();
mt3.start();
}
} /*
线程C买票出一张票,剩余票数:4
线程A买票出一张票,剩余票数:4
线程B买票出一张票,剩余票数:4
线程A买票出一张票,剩余票数:3
线程C买票出一张票,剩余票数:3
线程A买票出一张票,剩余票数:2
线程B买票出一张票,剩余票数:3
线程A买票出一张票,剩余票数:1
线程C买票出一张票,剩余票数:2
线程C买票出一张票,剩余票数:1
线程A买票出一张票,剩余票数:0
线程B买票出一张票,剩余票数:2
线程B买票出一张票,剩余票数:1
线程B买票出一张票,剩余票数:0
线程C买票出一张票,剩余票数:0
*/
//使用Runnable接口实现

public class MyThread implements Runnable {
int tickets = 5; @Override
public void run() {
while(tickets>0) {
System.out.println(Thread.currentThread().getName() + "买票出一张票,剩余票数:" + (--tickets));
}
} public static void main(String[] args) {
MyThread mt = new MyThread();
new Thread(mt,"线程A").start();
new Thread(mt,"线程B").start();
new Thread(mt,"线程C").start();
}
} /*
线程B买票出一张票,剩余票数:3
线程A买票出一张票,剩余票数:4
线程C买票出一张票,剩余票数:2
线程A买票出一张票,剩余票数:0
线程B买票出一张票,剩余票数:1
*/
//同一个线程不能重复启动,否则会出现异常

public class MyThread extends Thread {
int tickets = 5; @Override
public void run() {
while(tickets>0) {
System.out.println("买票出一张票,剩余票数:" + (--tickets));
}
} public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
mt.start();
mt.start();
}
} /*
Exception in thread "main" 买票出一张票,剩余票数:4
买票出一张票,剩余票数:3
买票出一张票,剩余票数:2
买票出一张票,剩余票数:1
买票出一张票,剩余票数:0
java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at test.MyThread.main(MyThread.java:17)
*/

    图释:

   

使用Thread类的内存情况

   

使用Runnable接口的内存情况

  面试题:请解释多线程的两种实现方式以及区别,并用代码验证?

    答:多线程需要一个线程的主类,这个类要么继承Thread类,要么实现Runnable接口;

      使用Runnable接口要比Thread类更好地实现数据共享的操作,并且使用Runnable接口可以避免单继承局限。

      代码如上。

 

Java基础学习总结 -- 多线程的实现的更多相关文章

  1. Java基础学习(八) - 多线程

    理解线程 进程是指一个内存中运行的应用程序,系统运行一个程序即是一个进程从创建,运行,结束的过程. 线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程. 多线程的特点是并发 ...

  2. Java基础学习篇---------多线程

    一.编写两种多线程的方法 (1).Thread(它是继承Runnable的子类) class MyThread extends Thread{ private int ticket = 5; @Ove ...

  3. Java基础学习笔记总结

    Java基础学习笔记一 Java介绍 Java基础学习笔记二 Java基础语法之变量.数据类型 Java基础学习笔记三 Java基础语法之流程控制语句.循环 Java基础学习笔记四 Java基础语法之 ...

  4. 尚学堂JAVA基础学习笔记

    目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...

  5. Java基础学习-- 继承 的简单总结

    代码参考:Java基础学习小记--多态 为什么要引入继承? 还是做一个媒体库,里面可以放CD,可以放DVD.如果把CD和DVD做成两个没有联系的类的话,那么在管理这个媒体库的时候,要单独做一个添加CD ...

  6. Java基础学习中一些词语和语句的使用

    在Java基础学习中,我们刚接触Java会遇到一些词和语句的使用不清的情况,不能很清楚的理解它的运行效果会是怎么样的,如:break,continue在程序中运行效果及跳转位置, 1.先来看看brea ...

  7. 转载-java基础学习汇总

    共2页: 1 2 下一页  Java制作证书的工具keytool用法总结 孤傲苍狼 2014-06-24 11:03 阅读:25751 评论:3     Java基础学习总结——Java对象的序列化和 ...

  8. java基础学习总结——开篇

    java是我学习的第一门编程语言,当初学习java基础的时候下了不少功夫,趁着这段时间找工作之际,好好整理一下以前学习java基础时记录的笔记,当作是对java基础学习的一个总结吧,将每一个java的 ...

  9. Java基础学习笔记(一)

    Java基础学习笔记(一) Hello World 基础代码学习 代码编写基础结构 class :类,一个类即一个java代码,形成一个class文件,写于每个代码的前端(注意无大写字母) XxxYy ...

随机推荐

  1. Echarts使用

    Echarts使用 |版权声明:此文为本人原创,望尊重原创 前言:     和朋友聊天的过程中,朋友提到了Echarts.我当时不知道那个是用来做什么的.回到家我就百度了,开始自己看文档学习.本文是自 ...

  2. iOS开发-闪退问题-解决之前上架的 App 在 iOS 9 会闪退问题

    最新更新:(2015.10.02) 开发环境: Delphi 10 Seattle OS X El Capitan v10.11 需使用下列 HotfixID: 30398, PAServer Hot ...

  3. 深入理解定位父级offsetParent及偏移大小

    前面的话 偏移量(offset dimension)是javascript中的一个重要的概念.涉及到偏移量的主要是offsetLeft.offsetTop.offsetHeight.offsetWid ...

  4. HTTP的长连接和短连接——Node上的测试

        本文主要从实践角度介绍长.短连接在TCP层面的表现,借助Node.JS搭建后台服务,使用WinHTTP.Ajax做客户端请求测试,最后简单涉及WebSocket.     关键字:长连接.短连 ...

  5. Power BI官方视频(1) Power BI Desktop 7月份更新功能概述

    2016年7月,Power BI Desktop进行了一些功能更新,提高整体的用户体验.同时也有一些新的和令人兴奋的功能.看看大概介绍,更新功能要点: 本文原文地址:Power BI官方视频(1) P ...

  6. android app反编译

    最新在反编译别人的apk,有时候看到别人的app有很炫的效果,就想知道别人是怎么样实现的,顺便自己参考,借鉴一下,下一次如果工作中碰到这个问题就知道怎么实现了.最近恰好放假三天,就研究了一下,一般别人 ...

  7. angularjs与jquery特效slidetoggle结合

    之前使用jquery的slidetoggle方法,可以轻易的实现元素的收缩展开:使用angularjs后,没有找到相关的方法,通过多方面查资料,自己写了个demo,展示slidetoggle的angu ...

  8. 使用Free Spire.XLS插入图表

    使用Free Spire.XLS插入图表 前言 最近在研究Office中间件,上网搜索了下,比较出名的有两个:Aspose和Spire,两者功能齐全,对Office的支持趋近完善,但售价不菲.仔细搜索 ...

  9. CSS字体记录

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAaYAAACnCAIAAADVOG9FAAAgAElEQVR4nOy9eXwcxZk/vL/9ve8eb7 ...

  10. Linux入门

    参考资料:http://www.92csz.com/study/linux/ [Linux系统目录结构] 登录系统后,在当前命令窗口下输入 ls / 你会看到 以下是对这些目录的解释: /bin bi ...