多线程 - 线程安全引入

具有线程安全的代码典型例子:

写一个代码,让主线程创建一个新的线程,由新的线程负责完成一系列的运算(比如:1 + 2 + 3 +... + 1000),再由主线程负责获取到最终结果。

但打印结果为 result = 0,略微思考,明白了要让 t 线程先执行完,然后再打印 result。补充,其实如果主线程直接就打印 result,此时得到的结果是啥,其实是无法预期的,由于线程之间的执行顺序不确定,主线程打印的 result 可能是还没有开始计算的初始值0,也可能是过程时候的中间结果,也可能是 t 线程计算完成之后的最终结果。

可以使用 sleep 来等待 t 线程结束,但问题是,不知道 t 线程到底要执行多久。

使用 join() ,就会严格按照 t 线程执行结束来作为等待的条件。什么时候 t 运行结束(计算完毕),什么时候,join 就结束等待。t 运行 1ms,join 就等待 1ms,t 运行 10s,join 就等待 10s,确保 join 之后得到的结果,一定是靠谱的结果。

如果我们要计算到 1 + ... + 100_0000_0000

这样只在一个线程中运算,运算量又非常大,我们就可以搞多个线程,分别运算,每个线程负责算一部分,又可以进一步的提高效率了。

这样就大大节省了时间,提升了效率。(注意:这里计算的时候,每一次结果都是不同的,就涉及到了“线程安全问题”)。

线程的状态

就绪:这个线程随时可以去 CPU 上执行(也包含在 CPU 上执行)

阻塞:这个线程暂时不方便去 CPU 上执行,在 Java 中,针对阻塞状态又做了进一步的细分。

Java 中,线程有如下几种状态:

        1.NEW:Thread 对象创建好了,但是还没有调用 start 方法在系统中创建线程。

        2.TERMINATED:Thread 对象仍然存在,但是系统内部的线程已经执行完毕了。

        3.RUNNABLE:就绪状态,表示这个线程正在 CPU 上执行,或者随时准备就绪可以去 CPU 上执行。

        4.TIME_WAITING 指定时间的阻塞,即到达一定时间之后,自动解除阻塞,使用带参数的 sleep 会进入这个状态,使用带有超时时间的 join 也会进入这个状态。

        5.WAITING 不带时间的阻塞(死等),必须要满足一定的条件,才会解除阻塞。join 或者 wait 都会进入 WAITING。

        6.BLOCKED 由于锁竞争引起的阻塞

如果发现某个进程卡住了,就可以使用 jconsole 这样的工具,查看这个进程中的一些重要线程的状态和调用栈,通过状态,就可以判断线程是否阻塞,已经是因为什么原因阻塞的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值