线程Thread

什么是线程?

线程是操作系统能够进行运算调度的最小单位,被包含在进程中。线程也叫作轻量级进程,在一个进程里可以创建多个线程,每个线程都有独立的计数器,堆,栈和局部变量,并且能够访问共享的内存变量

 

线程和进程的区别?

线程是一个轻量级进程,一个进程可以有多个线程,各条线程能够执行不同的任务,不同的进程使用不同的内存空间,而所有的线程共享相同的内存空间

 

创建线程的四种方法?

    1.继承Thread类

    2.实现Runnable接口,覆盖run()方法

    3.实现Callable接口

    4.通过线程池创建线程

 

 

Runnable还是Thread?

区别:实现过程步骤不一样,一个需要构造器入参,一个要实现Runnable接口的对象

由于java是单继承的,如果一个类继承了另一个类,再想实现多线程,这时候再继承Thread是不行的,因为这样就是多继承了,可是java不允许,所以如果要继承其他类,那么实现Runnable接口吧(java不能多继承,但是能实现多个接口啊)

并且Runnable适合于资源的共享   因为线程是独立的,所以局部变量不共享,而如果是实现Runnable接口,那么在开一个新线程new Thread(myRunnable,"线程的名字")时,所有的线程都共享接口内的资源(实现了Runnable接口的类的资源)

所以多线程主要以实现Runnable接口为主

 

为什么要使用多线程?

1)更多的处理器核心 : 随着cpu数量的增加,计算机更加擅长并行计算。一个程序作为一个进程,能创建多个线程,而一个时刻一个处理器只能运行一个线程,如果是单线程的话,再多的处理器也没用户,而使用多线程,能够同时利用多个处理器,提高执行效率

2)更快的响应时间: 将数据一致性不强的操作交给其他线程处理,优先响应用户的请求,缩短响应时间,提高用户体验

3)更好的编程模型 : java为多线程编程提供了良好的编程模型

 

线程的状态?

   新建,就绪,运行,阻塞,死亡

 

blocked和waiting的区别?

   进入waiting状态的线程等待唤醒后才有机会获取cpu的时间片来继续执行

   线程的blocked状态往往是无法进入同步方法来完成的,因为无法获取到与同步方法相关的锁

 

 

线程如何调度的?

操作系统分出时间片,线程获得时间片,当线程的时间片用完后发生线程调度,并等待下次分配的时间片。线程获得的时间片的多少决定了线程使用处理器资源的多少,线程优先级就是决定线程分配多少时间片的属性

注意:线程优先级不能作为程序正确性的依赖,因为操作系统可以完全不理会线程优先级

 

Thread类中的start()和run()方法的区别?

start()方法被用来启动新创建的线程,而且start()也是调用的run()方法,但是和直接调用run()不一样,当你调用run()方法时,只会在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程

 

start()?

start()方法将线程的状态由new变为Runnable,只是创建一个线程时,它会处于new状态,不会运行,只有调用start()方法后才会运行(start()方法的调用顺序不能决定线程的执行顺序,取决于jvm的调度算法)

注意:在线程的生命周期中,new->Runnable只会发生一次,因此,一个线程只能调用一次start()方法

 

run()?

run()方法只是一个普通的方法,只不过当线程调用了start()方法后,一旦线程被cpu调度,处于运行状态,线程才会去调用run()方法

run()方法的执行是不需要线程调用start()方法的,run()是一个普通的对象方法,所以线程可以随时调用run()方法,即使线程没有start()

创建两个线程后如果没有start(),而是直接run(),那么两个线程是顺序执行的(即实现并发的是Thread而不是run())

 

 

怎么理解Thread?

Thread也是一个java对象,只不过每个对象都对应一个线程,当一个线程结束,对应的Thread对象还能都用除了start()外的所有其他方法

 

Runnable和Callable的区别?

Runnable和Callable都代表那些要在不同线程中执行的任务,主要区别是Callable的call()方法可以返回值和抛出异常,Callable可以返回装有计算结果的Future对象

 

CyclicBarrier和CountDownLatch的区别?

CountDownLatch是一个线程等到另外N个线程执行完成之后才开始执行,CountDownLatch的await()方法会阻塞当前线程直到N变成0.CountDownLatch不能重用,即不能重新初始化或修改内部的计数器

CyclicBarrier可循环使用(重用),它要做的事情是让一组线程到达一个屏障(同步点)时被阻塞,直到最后一个线程到达屏障点时,所有被阻塞的线程再运行。如果没有调用足够次数的await()方法,则调用了await()方法的线程都会被阻塞

CyclicBarrier有个更高级的构造函数CyclicBarrier(int parts,Runnable barrierAction),会优先执行barrierAction

 

CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset()重置

 

java中的volatile?

volatile变量保证下一个读取操作会在前一个写操作之后发生

 

总结

1)wait()和notify/notifyAll()方法

wai()方法:

   线程进入waiting状态并且释放它所占有的锁标志,从而使别的线程有机会抢夺该锁,等到其他线程调用对象的notify或notifyAll()方法恢复

  wait()方法是一个本地方法,底层是通过一个叫做监视器锁的对象来完成的

notify/notifyAll()方法

   在同一个对象上调用notify/notifyAll方法,就可以唤醒对应对象上等待的线程了,notify只能随机唤醒monitor上的一个线程,而notifyAll是唤醒所有的线程

 

sleep/yield/join ?

sleep:

  sleep方法的作用是让当前线程暂停指定的时间

 wait方法依赖于同步,而sleep可以直接调用

 sleep只是暂时让出cpu的执行权,并不释放锁,而wait需要释放锁

yield:

  yield方法的作用是暂停当前线程,以便其他线程有机会执行,不过不能暂停指定的时间,也不能保证当前线程马上停止

  yield只能使同步优先级或更高优先级的线程有执行的机会

join

  等待调用join方法的线程结束,再继续执行

  作用是父线程等待子线程执行完成后再执行

 

wait和sleep的区别?

   sleep属于Thread类,wait属于Object类,sleep方法会使程序暂停指定时间,让出cpu给其他线程,但是假如持有锁的话,那么wait方法会把锁也释放了,但是sleep方法依然会持有锁

 

 

实现线程的三种方式:使用内核线程实现,使用户线程实现,使用用户线程和和轻量级进程混合实现

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值