java多线程嵌套_Java并发(一):多线程干货总结

一、进程 线程

进程:一个进程来对应一个程序,

每个进程对应一定的内存地址空间,并且只能使用它自己的内存空间,各个进程间互不干扰。

进程保存了程序每个时刻的运行状态,这样就为进程切换提供了可能。当进程暂停时,它会保存当前进程的状态(比如进程标识、进程的使用的资源等),在下一次重新切换回来时,便根据之前保存的状态进行恢复,然后继续执行。

对于单核计算机来讲,在同一个时间点上,游戏进程和音乐进程是同时在运行吗?

不是。 因为计算机的 CPU 只能在某个时间点上做一件事。

由于计算机将在“游戏进程”和“音乐进程”之间频繁的切换执行,切换速度极高,人类感觉游戏和音乐在同时进行。多进程的作用不是提高执行速度,而是提高 CPU 的使用率。

线程:一个进程就包括了多个线程,每个线程负责一个独立的子任务。这些线程是共同享有进程占有的资源和地址空间的。

这样在用户点击按钮的时候,就可以暂停获取图像数据的线程,让UI线程响应用户的操作,响应完之后再切换回来,让获取图像的线程得到CPU资源。从而让用户感觉系统是同时在做多件事情的,满足了用户对实时性的要求。

进程让操作系统的并发性成为可能,而线程让进程的内部并发成为可能。

多线程优点:参考多线程的优点

资源利用率更好

程序设计在某些情况下更简单

程序响应更快

多线程缺点:参考多线程的代价

设计更复杂

上下文切换的开销

增加资源消耗

上下文切换:

对于单核CPU来说(对于多核CPU,此处就理解为一个核),CPU在一个时刻只能运行一个线程,当在运行一个线程的过程中转去运行另外一个线程,这个叫做线程上下文切换(对于进程也是类似)。

由于可能当前线程的任务并没有执行完毕,所以在切换时需要保存线程的运行状态,以便下次重新切换回来时能够继续切换之前的状态运行。

所以一般来说,线程上下文切换过程中会记录程序计数器、CPU寄存器状态等数据。

说简单点的:对于线程的上下文切换实际上就是存储和恢复CPU状态的过程,它使得线程执行能够从中断点恢复执行。

虽然多线程可以使得任务执行的效率得到提升,但是由于在线程切换时同样会带来一定的开销代价,并且多个线程会导致系统资源占用的增加,所以在进行多线程编程时要注意这些因素。

二、创建、启动线程

继承Thread类

public classTest {public static voidmain(String[] args) {

MyThread thread= newMyThread();

thread.start();

}

}class MyThread extendsThread{private static int num = 0;publicMyThread(){

num++;

}

@Overridepublic voidrun() {

System.out.println("主动创建的第"+num+"个线程");

}

}

实现Runnable接口

public classTest {public static voidmain(String[] args) {

Thread thread= new Thread(newMyRunnable());

thread.start();

}

}class MyRunnable implementsRunnable{publicMyRunnable() {

}

@Overridepublic voidrun() {

System.out.println("子线程ID:"+Thread.currentThread().getId());

}

}

注意:创建并运行一个线程调用start()方法 而不是run()

三、Thread类/线程状态

e055084e5ba6f6e3c1a2ba3f99d0e4e1.png

1)getId  用来得到线程ID

2)getName和setName 用来得到或者设置线程名称。

3)getPriority和setPriority 用来获取和设置线程优先级。

4)setDaemon和isDaemon

用来设置线程是否成为守护线程和判断线程是否是守护线程。

守护线程和用户线程的区别在于:守护线程依赖于创建它的线程,而用户线程则不依赖。

举个简单的例子:如果在main线程中创建了一个守护线程,当main方法运行完毕之后,守护线程也会随着消亡。而用户线程则不会,用户线程会一直运行直到其运行完毕。在JVM中,像垃圾收集器线程就是守护线程。

5)Thread类有一个比较常用的静态方法currentThread()用来获取当前线程。

6)start方法

7)run方法

8)sleep方法  sleep相当于让线程睡眠,交出CPU,让CPU去执行其他的任务。sleep方法不会释放锁。

9)yield方法

调用yield方法会让当前线程交出CPU权限,让CPU去执行其他的线程。不会释放锁。

调用yield方法并不会让线程进入阻塞状态,而是让线程重回就绪状态。

10)join方法

假如在main线程中,调用myThread.join()方法,则main方法会等待thread线程执行完毕或者等待一定的时间。

如果调用的是无参join方法,则等待thread执行完毕,如果调用的是指定了时间参数的join方法,则等待一定的事件。

11)interrupt方法

详细讲解中断:

单独调用interrupt方法可以使得处于阻塞状态的线程抛出一个异常,它可以用来中断一个正处于阻塞状态的线程。

举例:

控制台输出:

进入睡眠状态

得到中断异常

run方法执行完毕

public classTest {public static void main(String[] args) throwsIOException {

Test test= newTest();

MyThread thread= test.newMyThread();

thread.start();try{

Thread.currentThread().sleep(2000);

}catch(InterruptedException e) {

}

thread.interrupt();

}class MyThread extendsThread{

@Ov

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值