上篇文章讲述了创建线程的常用方式

本篇主要分析一下Thread和Runnable两种方式创建线程的区别及联系

联系:

▶Thread类实现了Runable接口。

▶都需要重写里面Run方法。

区别:

▶Thread方式不支持多继承,Runnable方式支持多个实现

▶Runnable更容易实现资源共享,能多个线程同时处理一个资源。

疑惑分享:

本人在理解他们区别的时候

考虑到Thread类本身就是Runnable的实现类

所以产生了一个疑惑:-

为什么Runnable可以实现共享而Thread却不行呢

疑惑代码:

class Thread1 extends Thread {
int i = 100;
@Override
public void run() {

while (i > 0) {
try {
Thread.sleep(40L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (this) {

/*synchronized 不要直接放在run方法 应该放到循环里面 这样多个线程在循环的时候每次都能竞争锁 从而实现交替执行 否则一个线程执行完了另一个线程就没有执行的机会了*/
if (i > 0) {

/*

1.加判断是为了 如果当i=1的时候 此时两个线程都执行到了这里  一个线程得到锁进行减一操作那么i变为0 此时第二个线程再输出就会把0输出出来

2.第二个线程能够及时读取到i的值是由于synchronized既可以实现原子性又可以实现可见性*/

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

public class TestThread {

public static void main(String[] args) {

Thread1 te1 = new Thread1();

Thread t1 = new Thread(te1, "window1");

Thread t2 = new Thread(te1, "window2");

t1.start();

t2.start();

}

}

下面我们就来聊一聊(有共同疑惑的朋友们可以参考一下):

首先我们要清楚Thread和Runnable两种方式的本质区别在哪里

我们知道无论使用哪种方式最终都会通过 Thread类对象调用start方法进行开启线程

本质的区别就在于:

Thread方式是调用无参构造方法

Runnable方式是调用带有Runnable参数的有参构造方法

我们说过Thread类实现了Runable接口

以上疑惑代码中就是向Thread构造方法中传递了一个Tel1参数

看似与Runnable没有关系

但实质上是属于常说的Runnable方式调用

对应源码:Thread(Runnable target, String name)

那么有参和无参有什么区别是什么呢,为什么runnable能实现资源共享:

参考源码:

this.target = paramRunnable;

public void run()

{

if (this.target != null)

this.target.run();

}

有参:

如果是参数中Runnable不为空

那么Thread run方法中最终执行的方法实际上是传进来Runnable中的run方法

所以使用Runnable方式 无论new出多少个Thread对象

最终执行的任务都是一样的

自然就实现了资源的共享

无参:

每次new出Thread对象

他们对应的成员变量是互不影响的

所以就不能达到资源共享的效果

涉及知识点:

JMM关于synchronized的两条规定:

  1)线程解锁前,必须把共享变量的最新值刷新到主内存中

  2)线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新获取最新的值

   (注意:加锁与解锁需要是同一把锁)

通过以上两点,可以看到synchronized能够实现可见性。同时,由于synchronized具有同步锁,所以它也具有原子性

温馨提示:

▶在学习过程中理解一些概念或者结论不清晰的时候,一定要亲自动手结合着代码去分析,不要片面的理解一些知识点,一定要搞清实质。

▶本文内容如有不妥,恳请指正。

并发编程之多线程基础-Thread和Runnable的区别及联系(二)的更多相关文章

  1. C++11并发编程:多线程std::thread

    一:概述 C++11引入了thread类,大大降低了多线程使用的复杂度,原先使用多线程只能用系统的API,无法解决跨平台问题,一套代码平台移植,对应多线程代码也必须要修改.现在在C++11中只需使用语 ...

  2. python并发编程之多线程基础知识点

    1.线程理论知识 概念:指的是一条流水线的工作过程的总称,是一个抽象的概念,是CPU基本执行单位. 进程和线程之间的区别: 1. 进程仅仅是一个资源单位,其中包含程序运行所需的资源,而线程就相当于车间 ...

  3. java并发编程与多线程基础学习一

    学习url:https://www.cnblogs.com/lixinjie/p/10817860.html https://www.cnblogs.com/JJJ1990/p/10496850.ht ...

  4. 并发编程之多线程基础-join方法及优先级(五)

    join()方法作用 当在主线程当中执行到t1.join()方法时,就认为主线程应该把执行权让给t1 优先级 现代操作系统基本采用时分的形式调度运行的线程,线程分配得到的时间片的多少决定了线程使用处理 ...

  5. Java学习从菜鸟变大鸟之三 多线程中Thread 和Runnable的区别与运用

    多线程机制是java中的一个特点,掌握它对后面的知识的理解至关重要,是java工程师的必备知识,多线程指在单个程序中可以运行多个不同的线程执行的不同的任务,线程是一个程序内部的顺序控制流.进程是静态的 ...

  6. Python并发编程04 /多线程、生产消费者模型、线程进程对比、线程的方法、线程join、守护线程、线程互斥锁

    Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线程join.守护线程.线程互斥锁 目录 Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线 ...

  7. 三、多线程之Thread与Runnable的区别

    Thread与Runnable的区别(用三个窗口同时出售10张车票为例子) 运行代码 运行结果 分析 System.out.println("开始测试多线程");class MyT ...

  8. Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别

    一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...

  9. Java并发编程笔记之基础总结(二)

    一.线程中断 Java 中线程中断是一种线程间协作模式,通过设置线程的中断标志并不能直接终止该线程的执行,而是需要被中断的线程根据中断状态自行处理. 1.void interrupt() 方法:中断线 ...

随机推荐

  1. axios请求报Uncaught (in promise) Error: Request failed with status code 404

    使用axios处理请求时,出现的问题解决 当url是远程接口链接时,会报404的错误: Uncaught (in promise) Error: Request failed with status ...

  2. select(有局限性),jq循环添加select的值

    加载的时候改变select的默认值,只需改变select的value值 $("#one").val(@ViewBag.val);//@ViewBag.val是要默认选中的值的val ...

  3. OpenLayers 3 实现轨迹回放

    function PathBack() { var PVLayer = new ol.layer.Vector({ source: new ol.source.Vector({}) }); var p ...

  4. Oracle SQL语句优化34条

    非常好用的SQL语句优化34条 1)选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE 的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 dri ...

  5. springboot从入门到精通(二)

    这一节我们一起用springboot开发一个应用程序,应用程序里的核心概念是玩家获取英雄列表上的英雄信息. 1.定义实体模型: 代码如下: package com.dota.herolist.enti ...

  6. Csharp:操作存儲過程輸出參數,和返回值

    /// <summary> ///塗聚文 存儲過程輸出參數,和返回值 /// 20131030 /// Geovin Du /// </summary> /// <par ...

  7. rest-framework框架——解析器、ur控制、分页、响应器、渲染器、版本

    一.解析器(parser) 解析器在reqest.data取值的时候才执行. 对请求的数据进行解析:是针对请求体进行解析的.表示服务器可以解析的数据格式的种类. from rest_framework ...

  8. Popularize what is heart of mobile phone?

    From: http://tech.sina.com.cn/mobile/n/2014-09-29/08399657494.shtml 只谈核数没意义 带你重新认识手机SoC 2014年09月29日  ...

  9. 用nodejs做一个svn密码修改页面

    linux上配置好svn服务后,管理修改密码还得去手工修改passwd这个文件,略麻烦,其实网上应该有配套的web管理修改界面程序.但我想自己用nodejs写一个,因为用node不用配置复杂的服务器. ...

  10. linux C之判断文件或目录是否存在 access函数

    http://blog.sina.com.cn/s/blog_6a1837e90100uh5d.html access():判断是否具有存取文件的权限 相关函数    stat,open,chmod, ...