java多线程的概念_Java多线程常见概念

进程和线程的区别

进程是一个独立的运行环境,而线程是在进程中执行的一个任务。他们两个本质的区别是是否单独占有内存地址空间及其它系统资源(比如I/O):

进程单独占有一定的内存地址空间,所以进程间存在内存隔离,数据是分开的,数据共享复杂但是同步简单,各个进程之间互不干扰;而线程共享所属进程占有的内存地址空间和资源,数据共享简单,但是同步复杂。

进程单独占有一定的内存地址空间,一个进程出现问题不会影响其他进程,不影响主程序的稳定性,可靠性高;一个线程崩溃可能影响整个程序的稳定性,可靠性较低。

进程单独占有一定的内存地址空间,进程的创建和销毁不仅需要保存寄存器和栈信息,还需要资源的分配回收以及页调度,开销较大;线程只需要保存寄存器和栈信息,开销较小。

线程组(ThreadGroup)

每个Thread必然存在于一个ThreadGroup中,Thread不能独立于ThreadGroup存在。执行main()方法线程的名字是main,如果在new Thread时没有显式指定,那么默认将父线程(当前执行new Thread的线程)线程组设置为自己的线程组。

Start和run的区别

Start()会创建一个新的子线程并启动

Run()只是Thread的一个普通方法的调用

Thread和Runnable关系

Thread是实现了Runnable接口的类,使得run支持多线程

因类的单一继承原则,推荐多使用Runnable接口

1 public static voidmain(String[] args) {2

3 new Thread(newRunnable() {4 public voidrun() {5 System.out.println("Runnable running..");6 }7 }) {8 public voidrun() {9 System.out.println("Thread running..");10 };11 }.start();12 }

输出结果为

Thread running..

继承Thread类,那么在调用start的方法时会去调用Thread的子类的方法

如何给run()方法传参

构造函数传参

成员变量传参

回调函数传参

如何实现处理线程的返回值

主线程等待法(新建一个属性来存返回值,当这个属性还没值的时候,就等待,直到它有值)

使用Thread类的join()阻塞当前线程以等待子线程处理完毕

通过Callable接口实现,通过FutureTask 或线程池获取(推荐)

Sleep和wait区别

Sleep是Thread类的方法,wait是Object类的方法

Sleep方法可以在任何地方使用

Wait方法只能在synchronized方法或synchronized块中使用

Thread.sleep只会让出CPU,不会导致锁行为的改变

Object.wait不仅让出CPU,还会释放已经占有的同步资源锁

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public classThreadTest {2 public static voidmain(String[] args) {3 final Object lock = newObject();4 new Thread(newRunnable() {5 @Override6 public voidrun() {7 System.out.println("A is waiting to get lock");8 synchronized(lock) {9 try{10 System.out.println("A get lock");11 Thread.sleep(20);12 System.out.println("A get do wait method");13 Thread.sleep(1000);//只会让出CPU,不会导致锁行为的改变

14 System.out.println("A is done");15 } catch(InterruptedException e) {16 e.printStackTrace();17 }18 }19 }20 }).start();;21 try{22 Thread.sleep(10);//让A先执行

23 } catch(InterruptedException e1) {24 e1.printStackTrace();25 }26 new Thread(newRunnable() {27 @Override28 public voidrun() {29 System.out.println("B is waiting to get lock");30 synchronized(lock) {31 try{32 System.out.println("B get lock");33 System.out.println("B is sleeping 10 ms");34 lock.wait(10);//不仅让出CPU,还会释放已经占有的同步资源锁

35 System.out.println("B is done");36 } catch(InterruptedException e) {37 e.printStackTrace();38 }39 }40 }41 }).start();;42 }43 }

举例

d3a6672b9d6e7ad96da92a751b703343.png

等待池

假设线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁,同时线程A就进入到了该对象的等待池中,进入到等待池中的线程不会去竞争该对象的锁

Notify和notifyAll区别

notifyAll会让所有处于等待池的线程全部进入锁池去竞争获取锁的机会

notify只会随机选取一个处于等待池中的线程进入锁池去竞争获取锁的机会

yield

当调用Thread.yield()函数时,会给线程调度器一个当前线程愿意让出CPU使用的暗示,但是线程调度器可能会忽略这个暗示

Interrupt

如果线程处于被阻塞状态,那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常。

如果线程处于正常活动状态,那么会将该线程的中断标志设为true,被设置中断标志的线程将继续正常运行,不收影响。

e1d596ef9cde9dfb36e3e75e30a6f288.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值