`
z2367570158
  • 浏览: 6780 次
社区版块
存档分类
最新评论

JAVA之线程并发

阅读更多

最近表示被各种并发情况搞的无比蛋疼又神伤,加之在搞socket通信这种中下层玩意,简直日渐憔悴。嗯不过每一次走得更高更远都是一个浪漫和内涵的故事,所以这次来把并发搞搞清楚

 

首先来说一个老生常谈的问题

并发并行的区别,然后再说说进程和线程的区别,已然看到无数学长学姐笔试面试碰到这种题

 

以下大多出自互联网,如有错误求大神指正

 

先来说并发并行

由于这篇文章转载太广。。。我着实不知道到底哪个是原文。。。就昧着良心盗用下图片。。。


 这是一只立志把JAVA并发编程的书都送进火堆烧掉的老鼠。。。我们假设一个火堆烧掉左边一大堆书需要10秒,则如果不算老鼠运输时间,烧书只要10秒完成

 

 

现在我们加倍,两堆书两只老鼠两个火堆,可以预见,左边两堆书两个火堆烧,去掉老鼠运输时间,则烧书还是只要10秒。

 

 

那么这种情况呢,两堆书两只老鼠一堆火,如果只计算烧书时间,那么可以知道两堆书一堆火要20秒,就是说无论两只老鼠的运输效率怎么高,管理模式怎么科学,烧掉这些蛋疼的书还是最少要20秒。

 

 

从上面两种情况可以看出,两堆火两堆书,这就是并行,两堆书一堆火,这就是并发。  

而如我们所见,烧书的过程不只是火在烧,还有老鼠在运输,如果每次老鼠运输的书是书堆的1/10,即火烧要1秒,但是他来去都要2秒,即来回要4秒。

两堆火两堆书的情况是  两只老鼠同时开始同时结束,各跑了9个半来回(最后一次运到就好),用了38秒。

一堆火两堆书的情况是  一只老鼠运到火堆时另一只开始运,则两只老鼠交替,两只老鼠也都是各跑了9各半来回,但由于有先后次序,第一只开始后两秒两只才一起运输起来,则一共要40秒

(卧槽博主的逻辑要爆了感觉尤其是连续写了12小时代码以后!!!如果你发现博主的逻辑错了,没问题,博主现在连博主是人这种简单命题都开始怀疑了,简直就是代码机器!!!)

 

 

所以可见,一个火堆和两个火堆的最后效率是基本差不多的,怪不得那些MBA的挣钱要比程序猿高!!!这里就牵扯到系统什么时间片划分什么什么的balabala

PS注:上面除了第一幅第二幅图为盗用。。。其他文字和第三幅图都是我手写和手PS的,如果作者看到觉得侵犯了你的权益请先联系我立马删除。。。(好吧负罪感大大减轻)

 

以上就是并发和并行的区别,换句话说,就像一个人(cpu)喂2个孩子(程序),轮换着每人喂一口,表面上两个孩子都在吃饭,其实同时只有一个孩子在吃饭。并行,就是2个人喂2个孩子,两个孩子也同时在吃饭。

 

再来说进程与线程

 

摘自:http://ifeve.com/java-concurrency-cookbook/

进程是以独立于其他进程的方式运行的,进程间是互相隔离的。一个进程无法直接访问另一个进程的数据。进程的资源诸如内存和CPU时间片都是由操作系统来分配。

 

 

线程又被称为轻量级进程。每个线程有它独自的调用栈, 但是在同一进程下的线程又能互相访问它们间的共享数据。每个线程都有它独自的缓存。如果一个线程读取了某些共享数据,那么它将这些数据存放在自己的缓存中以供将来再次读取。

 

一个JAVA应用程序默认以一个进程的形式运行着。在一个JAVA程序中,你将协同多个不同的线程一起完成并行运算或实现异步行为。

 

我们可以把进程类比为一个工厂车间,它代表CPU所能处理的单个任务,为了方便我们处理,假设由于工厂(CPU)电力有限,同时只能保证一个车间运作,即一个CPU一次只运行一个进程,而不是什么时间片什么balabala我也不太懂。。。

好。。。车间是一个进程,一个车间里面有很多工人,他们协同完成一个任务,(注意我这里可以避开了说他们在一起同时工作,因为这里不是一个并发过程),车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。

而如果你从你们车间跑到别的车间去,就会发现门口一个大牌子上面写着“闲人免进”,好了闲人回到你的车间。。。这象征一般进程间是不共享数据的。

 

以上是进程和线程的区别。

 

这里有一个有意思的现象,你在车间里相当于一个线程,每个线程可以共享内存数据,好,厕所是车间里的一个数据,你可以使用,别人也可以使用,好,然后大家一起使用,好,然后大家同时使用。。。这不太好吧。。。但是确实线程是可以同时使用数据的啊。

这里就会牵扯到一个线程锁的问题

 

摘自http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966606.html

 

synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。 
1. synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。如: 
public synchronized void accessVal(int newVal); 
synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能

执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行

状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有

一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)

。 
在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成

员变量的访问。 
synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为

synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。当然我们可

以通过将访问类成员变量的代码放到专门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供

了更好的解决办法,那就是 synchronized 块。 
2. synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下: 
synchronized(syncObject) { 
//允许访问控制的代码 

synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行,具体机

制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。  

 

 博主自己也是测试了很多代码在线程锁这里,总之这里是一个繁琐的过程,由于本身程度不高,JVM没有研究过,大一也没有看过操作系统原理,只能半路出家,试着理解,如果有错误还请大家多多指教。

 

推荐几个博客   http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966606.html就是上边线程锁的转载地址,里面有好多例子,篇幅原因没有转载,大家可以去看看,自己测试一下

                        http://ifeve.com       一个并发编程的网站,是博主的某一届未曾谋面的大神学长在搞的一个网站,由于是比较专业的并发编程问题,所以我们这种渣渣还是早早退散了OTZ

 

/**求知对我们而言最根本的,也许不是为了让我们变得更加高级,对人生报更多奢望——而是为了让我们更自由。只不过要想真正在知识里看到自由,需要恒久的努力与谦卑,以及不管懂了多少依然充满了对这个世界的好奇心

我早有觉悟*/

 

 


  

 

  • 大小: 28.5 KB
  • 大小: 30.3 KB
  • 大小: 45.5 KB
6
4
分享到:
评论
6 楼 肆无忌惮_ 2014-07-18  
I白I 写道
I白I 写道
楼主举的例子,老鼠烧书那个,运输来回是5个半来回,一共是跑9次,而不是9个半来回,服楼主了。所以时间也是并发18秒,并行20秒,楼主多算了20秒

我说反了,是并行18秒,并发20秒。。

每次搬走1/10,总共跑10次,应该是9个半来回吧?
5 楼 smiky 2014-07-18  
好例子啊,进侧所然后关门,其它人就要等,出来后开门,别人进
4 楼 liujiaoshui 2014-07-18  
为什么不说并行,串行呢,名字搞得多别扭
3 楼 I白I 2014-07-18  
I白I 写道
楼主举的例子,老鼠烧书那个,运输来回是5个半来回,一共是跑9次,而不是9个半来回,服楼主了。所以时间也是并发18秒,并行20秒,楼主多算了20秒

我说反了,是并行18秒,并发20秒。。
2 楼 I白I 2014-07-18  
楼主举的例子,老鼠烧书那个,运输来回是5个半来回,一共是跑9次,而不是9个半来回,服楼主了。所以时间也是并发18秒,并行20秒,楼主多算了20秒
1 楼 冰上王国 2014-07-18  
两个老鼠一个火堆。。。41s嘛

相关推荐

    Java 模拟线程并发

    Java 模拟线程并发是编程领域中的一个重要概念,尤其在多核处理器和高并发应用中,理解并熟练掌握线程并发技术对于提升程序性能至关重要。在Java中,线程并发可以通过多种方式实现,包括继承Thread类、实现Runnable...

    java 多线程并发实例

    在Java编程中,多线程并发是提升程序执行效率、充分利用多核处理器资源的重要手段。本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是...

    java多线程并发

    java多线程并发的在新窗口

    JAVA多线程并发编程

    线程并发的使用可以显著提升程序处理能力,例如在服务器端处理大量用户请求时,如果每个请求都由单独的线程处理,那么处理速度将大大提高。但同时,多线程并发也会引入一些问题,如数据竞争和同步问题。 为了解决...

    java多线程并发编程知识导图笔记.xmind

    java多线程并发编程知识导图笔记.xmind

    java多线程并发控制[参照].pdf

    java多线程并发控制[参照].pdf

    java线程与并发编程实践

    Java线程与并发编程实践是Java开发者必备的技能之一,特别是在多核处理器和高并发应用环境中,有效地管理和利用线程能极大地提升程序的性能。本书《java线程与并发实践编程》由Jeff Friesen撰写,2017年2月出版,...

    java多线程并发实战和源码

    Java多线程并发实战与源码分析是Java开发中至关重要的一部分,它涉及到程序性能优化、系统资源高效利用以及复杂逻辑的正确同步。本书主要聚焦于Java多线程的基础理论和实际应用,虽然书中实例和源码相对较少,但仍然...

    java多线程并发演示

    实现多线程的并发执行,能演示操作系统的时间转轮调度算法对多线程程序执行的影响效果,能控制一个或多个线程的执行情况。

    Java_多线程与并发编程总结.doc

    Java多线程与并发编程是Java开发中至关重要的一部分,它涉及到如何高效地利用CPU资源,以实现程序的并行执行。在操作系统层面,多任务和多进程是通过分配不同的内存空间来实现的,而线程则共享同一进程的内存,这...

    Java多线程与并发库高级应用

    并发库高级应用\多线程\Java

    java多线程与高并发视频

    java多线程与高并发java多线程与高并发java多线程与高并发

    JAVA多线程并发操作全局变量

    NULL 博文链接:https://toknowme.iteye.com/blog/2212529

    java多线程和并发.pdf

    Java多线程与并发编程是Java语言中用于处理多任务执行的关键技术,它能够帮助开发者设计出能够有效应对高并发请求的应用程序。在现代的线上(Online)和离线(Offline)应用中,合理利用多线程技术可以大幅提高系统...

    Java多线程并发实战

    ### Java多线程并发实战知识点解析 #### 一、引言 在计算机科学领域,**多线程**和**并发**技术是现代软件开发中不可或缺的一部分。随着处理器核心数量的增加,利用多线程和并发可以显著提高应用程序的性能和响应...

    java多线程查询数据库

    多线程并发查询允许我们将一个大任务分解为多个小任务,每个任务在不同的线程上独立运行,从而提高查询效率。在数据库查询中,这通常适用于处理分页数据或执行并行查询。 ### 2. 线程池 Java中的线程池是通过`java....

    java 多线程高并发相关资料收集

    在Java编程领域,多线程和高并发是两个至关重要的概念,它们对于构建高效、可扩展的系统至关重要。本文将围绕“Java多线程高并发相关资料收集”这一主题,详细探讨这两个领域的核心知识点。 首先,多线程是指在单个...

    java多线程并发编程例子

    Java多线程并发编程是Java开发中的重要领域,特别是在服务器端和高并发应用中不可或缺。`java.util.concurrent`包提供了丰富的工具类,帮助开发者更好地管理线程和优化并发性能。以下将详细介绍标题和描述中涉及的...

    JAVA并发多线程的面试问题及答案-java多线程并发面试题.docx

    线程间交互是 Java 多线程并发编程中非常重要的一方面。面试官通常会问一些相关的问题,以检测候选者的基础知识和实际编程能力。 * wait 和 sleep 方法的不同? 这个问题是检测候选者对 wait 和 sleep 方法的理解和...

Global site tag (gtag.js) - Google Analytics