线程-整合多篇文章

参照资源:http://www.mamicode.com/info-detail-517008.html

一、进程、线程区别

进程:每个进程都有独立的代码和数据空间,进程切换会有很大的开销,一个进程包含1~n个线程

线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器,线程切换开销小

都有五个阶段:创建、就绪、运行、阻塞、终止。

多进程:操作系统能运行多个任务

多线程:同一个程序中多个顺序流在执行。

二、Thread与Runable的区别

  1.如果一个类继承Thread,不适合资源共享

    实现了Runable接口,很容易实现资源共享

适合多个相同的程序代码去处理同一个资源

  2.避免了Java中单继承的限制

  3.增加程序的健壮性,代码可被多个线程共享,代码和数据独立

三、注意:在Java中,每次程序运行至少启动2个线程,main 垃圾回收线程

每当使用Java命令执行一个类时,都会启动一个JVM,每个jvm就是在操作系统中启动了一个进程。

四、线程方法的比较

sleep()和yield()

sleep(long millis)在指定的毫秒数内让线程休眠

yield()暂停当前正在执行的线程对象,并执行其他线程

  运行状态---->可运行状态

  让当前线程回到可运行的状态,以运行具有相同优先级的其他线程获得运行机会,让相同优先级的线程之间能适当的轮转执行,实际中无法保证yield()达到让步目的(让步的线程可能会被线程调度程序再次选中)

sleep()使当前线程进入停滞状态,执行sleep()的线程在指定的时间内肯定不会被执行;

yield()只是使当前线程重新回到可执行状态,执行yield()的线程有可能在进入到可执行状态后马上又被执行。

sleep 方法使当前运行中的线程睡眼一段时间,进入不可运行状态,这段时间的长短是由程序设定的,

yield 方法使当前线程让出 CPU 占有权,但让出的时间是不可设定的。

实际上,yield()方法对应了如下操作:先检测当前是否有相同优先级的线程处于同可运行状态,如有,则把 CPU  的占有权交给此线程,否则,继续运行原来的线程。所以yield()方法称为“退让”,它把运行机会让给了同等优先级的其他线程

sleep 方法允许较低优先级的线程获得运行机会,

yield()  方法执行时,当前线程仍处在可运行状态,所以,不可能让出较低优先级的线程些时获得 CPU 占有权。

在一个运行系统中,如果较高优先级的线程没有调用 sleep 方法,又没有受到 I\O 阻塞,那么,较低优先级线程只能等待所有较高优先级的线程运行结束,才有机会运行。

 

   wait和sleep区别
共同点:

1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。
2. wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException。
   如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep /join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。
   需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用 interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到 wait()/sleep()/join()后,就会立刻抛出InterruptedException 。
不同点:
1. Thread类的方法:sleep(),yield()等
   Object的方法:wait()和notify()等
2. 每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。
   sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3. wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
4. sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
所以sleep()和wait()方法的最大区别是:
    sleep()睡眠时,保持对象锁,仍然占有该锁;
    而wait()睡眠时,释放对象锁。
  但是wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException(但不建议使用该方法)。

 

join()等待该线程终止(调用此方法的线程结束,其他线程才能执行)

interrupt() 中断某个线程(若线程打开了某个资源还没关闭/run方法还没执行完就强制结束线程,会导致资源无法关闭)

五、线程同步

1.sychronized

1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;
2)是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。

2、除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;

3、synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;

A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。

B.每个对象只有一个锁(lock)与之相关联。

C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

posted on 2017-09-30 11:15  青葙  阅读(100)  评论(0编辑  收藏  举报