多线程

『来源:HollisChuang


1、进程和线程的区别

  进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每一个进程都有一个自己的地址空间。进程具有一定的独立功能。

  线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程在程序中是独立的并发的执行流。

  线程自己不拥有系统资源,它与父进程的其他线程共享该进程所拥有的全部资源,线程只拥有一点在运行中必不可少的资源,比如:自己的堆栈、自己的程序计数器和自己的局部变量。

  一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行。线程的执行时抢占式的,也就意味着当前运行的线程在任何时候都有可能被挂起,以便另外一个线程可以运行。

区别:

  ① 一个程序至少有一个进程,一个进程至少有一个线程

  ② 内存共享:进程在执行过程中拥有独立的内存单元(一个进程崩溃后,在保护模式下不会对其它进程产生影响);

  而多个线程共享进程提供的内存(拥有自己的私有栈空间只是作为运行需要的极少内存),从而极大地提高了程序的运行效率,但一个线程死掉就等于整个进程死掉。所以多进程的程序要比多线程的程序健壮

  ③ 因为线程的划分尺度小于进程,使得多线程程序的并发行高。

  ④ 执行过程:进程独立执行;线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

  ⑤ 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。

  但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

参考链接
https://blog.csdn.net/mxsgoden/article/details/8821936

  

2、并行和并发的区别和联系

  并行:是指在同一时刻,有多条指令在多个处理器上同时执行。

  并发:是指在同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行,使得在宏观上具有多个进程同时执行的效果。

  

3、同步和异步

  同步:可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。

  异步:执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,通过状态、通知和回调来通知调用者,从而完成一个完整的流程。

  同步在一定程度上可以看做是单线程,这个线程请求一个方法后就待这个方法给他回复,否则他不往下执行(死心眼)。

  异步在一定程度上可以看做是多线程的,请求一个方法后,就不管了,继续执行其他的方法,等有返回值以后,再回来执行程序
  

4、多线程的实现方式,有什么区别

实现方式:
① 继承Thread

  继承Thread类,重写run()方法,实例化线程类,调用start()方法启动线程。
  
  
② 实现Runnable接口

  实现Runnable接口并重写run()方法,创建Runnable实例,并以此实例作为Thread类的target参数创建Thread对象,调用Thread对象的start()启动线程
  

③ 使用Callable接口和Future来创建线程
  
  实现Callable接口,并实现call()方法,并创建Callable实例,然后使用FutureTask对象来包装Callable实例,使用FutureTask对象作为Threadtarget来创建并启动线程
  
区别:
  Runnable接口和Callable接口的方式基本相同(实现Runnable接口和Callable接口仅仅是创建了一个任务,但是仍然需要Thread类来创建线程并启动),他俩唯一区别只是Callable接口实现方法有返回值,并且也可以声明抛出异常而已,可以归为一类。
  
1、继承Thread实现线程

  ① 已经继承了Thread类,不能继承其他类

  ② 获取当前线程,可以直接使用this来获得
  
2、实现Runnable接口、Callable接口创建线程

  ①实现的是接口,还可以继承其他类

  ② 多个线程可以共享同一个target对象,适合多个相同的线程来处理同一份资源的情况

  ③ 获取当前线程必须用Thread.currentThread()方法来获得

http://www.liuzk.com/183.html
  

5、什么叫守护线程

  在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程) 。

  守护线程, 是指在程序运行的时候在后台提供一种通用服务的线程, 比如垃圾回收线程就是一个很称职的守护者。

  并且这种线程并不属于程序中不可或缺的部分。因此只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。

  可以通过调用线程的setDaemon()方法,传入参数true,将一个用户线程设置为一个守护线程
  
这里有几点需要注意:
  (1) thread.setDaemon()必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。

  (2) 在Daemon线程中产生的新线程也是Daemon的。

  (3) 不要认为所有的应用都可以分配给Daemon来进行服务,比如读写操作或者计算逻辑。 因为你不可能知道在所有的User完成之前,Daemon是否已经完成了预期的服务任务。一旦User退出了,可能大量数据还没有来得及读入或写出,计算任务也可能多次运行结果不一样。这对程序是毁灭性的。
  

6、如何停止一个线程?

  ① 设置一个标志位 需要用volatile来修饰,保证线程读取时标志位是最新数据

  ② 在sleep状态下使用interrupt()方法,程序抛出InterruptedException,捕捉这个异常来结束程序。但仍要调用Thread.currentThread().interrupt()恢复中断,让线程退出。
  

7、什么是线程安全?

  线程安全就是多线程访问同一代码,不会产生不确定的结果。

如何保证线程安全
对非安全的代码进行加锁控制;
使用线程安全的类;
多线程并发情况下,线程共享的变量改为方法级的局部变量。

https://blog.csdn.net/suifeng3051/article/details/52164267
  

8、synchronized 和 lock的区别

主要相同点:

  Lock能完成synchronized所实现的所有功能

主要不同点:

  Lock有比synchronized更精确的线程语义和更好的性能。

  Lock的锁定是通过代码实现的,而synchronized是在JVM层面上实现的,synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。

  Lock还有更强大的功能,例如,它的tryLock方法可以非阻塞方式去拿锁。

  Lock锁的范围有局限性,块范围,而synchronized可以锁住块、对象、类。
  

9、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

现在分两种情况来讨论:

  1.当前线程调用的是synchronized普通方法(相对于static方法);
  2.当前线程调用的是synchronized static方法。

1.当前线程调用的是synchronized普通方法(相对于static方法)时,其它线程是否可进入此对象的其它方法:

1)其它方法是加了synchronized的普通方法,不能;

2)其它方法是没加synchronized的普通方法,能;

3)其它方法是synchronized的static方法,能;

4)其它方法是没加synchronized的static方法,能。

5)如果这个方法内部调用了wait,则可以进入其他synchronized方法。
(因为当前线程执行同步代码块或同步方法时,程序执行了同步监视器对象的wait()方法,则当前线程暂停,并释放同步器)

2.当前线程调用的是synchronized static方法,其它线程是否可进入此对象的其它方法:

1)其它方法是加了synchronized的普通方法,能;

2)其它方法是没加synchronized的普通方法,能;

3)其它方法是synchronized的static方法,不能;

4)其它方法中有synchronized(xxx.class)的,不能;

5)其它方法是没加synchronized的static方法,能。

所谓的synchronized(xxx.class)就是同步代码块:

public void method5(){
        synchronized(xxx.class){
                System.out.println("this is a  synchronized static method——method5.");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    }

参考链接:java线程之——synchronized的注意细节

  

10、启动一个线程是用run()还是start()?

  启动一个线程是使用star(),启动线程后,系统会把该线程的run()方法当成线程执行体来处理。

  如果使用的是run()方法,则run()方法会被立即执行,而且在run()方法返回之前其他线程无法并发执行。

  因此如果直接调用线程对象的run()方法,系统会把线程对象当成一个普通对象,而run()方法也是一个普通方法,而不是线程体。
  

11、wait和sleep的区别

  sleep()方法是Thread类中方法,而wait()方法是Object类中的方法。

  sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是它的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁。

  而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备。
  

12、notify()和notifyAll()的区别

notify():
  唤醒在次同步监视器上等待的单个线程,如果所有线程都在此同步监视器上等待,则会选择唤醒其中一个线程。

  选择是任意性的。只有当前线程放弃对该同步监视器的锁定后(使用wait()方法),才可以执行被唤醒的线程

notifyAll():
  唤醒在此同步监视器上等待的所有线程。只有当前线程放弃该同步监视器的锁定后,才可以执行被唤醒的线程。
  

13、线程池的作用
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容

  • 线程概述 线程与进程 进程  每个运行中的任务(通常是程序)就是一个进程。当一个程序进入内存运行时,即变成了一个进...
    闽越布衣阅读 1,009评论 1 7
  • 下面是我自己收集整理的Java线程相关的面试题,可以用它来好好准备面试。 参考文档:-《Java核心技术 卷一》-...
    阿呆变Geek阅读 14,800评论 14 507
  • 没创业前是打工,所以什么打工者的心态都见过也很熟悉了,现在换成老板也很好对症下药。 员工无非三样东西,钱,权,情。...
    蔚蓝的宁静阅读 790评论 0 50
  • ​当你有能力的时候,一定要狠踹生活。 因为生活绝不会因为你胆小怯懦,什么的都没干,而饶了你。 奇葩说里,一个22岁...
    封铌阅读 1,363评论 3 5
  • 流云镇虽只是个小镇,偏居一隅,但胜在位置佳,身侧便是源远流长的清水河。在四处环绕的青山堆里,走水路便尤为平顺方便,...
    思依阅读 651评论 3 3