迈向Java高级程序员(二)-----先从并发开始(线程篇)

       很多人写关于线程的时候都是写一堆原理在开头。我不讲,因为我讲不好。废话不多说直接看代码。

       Java的Thead类就是Java实现线程的载体。为啥是Thread。没这么多为什么,是张三还是李四不总得有个名吗。

        Java有个约定,写个类有个main方法,这个类就可以直接run,入口就是这个main方法。main方法执行的时候Jvm无形中就启动了一个线程来执行要干得事,这个无形的线程可以通过Thread类提供的静态方法拿到。我们来看一段代码:

样例代码

执行结果:

执行结果

看到没有,真的有个无形的线程,而且这个线程的名字就叫main。这个方法你无论执行执行多少次,结果都是一样的。因为这是Java默认的。

既然知道了Java的代码执行时总是在一个线程里,那我们来看看这个线程类Thread到底是什么个玩意。


Thead类型

这里提供了一个信息,Thread类是一个实现了Runnable接口的类,我们先记着。

然后我们看下Thread提供了哪些方法来方便你做事。我们再来逐个讲解其用法:

1、public synchronized void start()     启动线程的方法。调用本地方法start0()来告诉jvm线程一准就绪,可以调run方法来执行来。

2、public void run()                              执行向线程提交的任务。

3、public void interrupt()                       用于主动中断线程。

4、public static boolean interrupted()   清除线程的中断状态,如果线程调用此方法前是中断的,则清除其中断状态,并且返回ture,否则返回false。

5、public boolean isInterrupted()         获取线程当前中断状态,true代表中断

6、public final native boolean isAlive    获取线程的存活状态

7、public static int activeCount()         获取线程活动的数量,因为一个线程在执行期间可以创建线程,这些线程会记录在当前线程维护的一个线程组内,包括当前线程也在内。这个方法获取到的最小值为1.

8、public static native Thread currentThread() 本地静态方法,获取当前执行线程对应的Thread类实例

9、public static native void yield();   本地静态方法,让当前正在执行的线程让出CPU,让其他线程执行。

10、public static native void sleep(long millis);让当前线程暂停执行若干毫秒。我们通常写demo会用此方法模拟一个耗时操作。此方法不会让出当前执行线程占用的CPU。

11、public static void sleep(long millis, int nanos) 作用同方法13,看了下源码感觉没什么用。

12、public final synchronized void join(long millis)  用与线程协作,例如。我有两件事情A、B,A可能需要先执行一段时间,才会用到B的结果,B是完全独立的。此时就可以分别启动A、B两个线程来做事。A中使用B.join方法。假设A认为5秒内B可以执行完,那就使用B.join(5000)。等B5秒钟。5秒种后不管B执行怎么养了A继续执行。如果一定要得到B的结果,可直接使用B.join()或者B.join(0),代表永久等待,直至B结束任务。

13、public final synchronized void join(long millis, int nanos) 等同于方法12

14、public final void join() 等同与直接用方法12 join(0);

其他一些,直接对属性操作的方法我们就不列举了。

我们主要来针对这14个方法来探究下:

1、start方法已在介绍方法时说明,此处就不在说了

2、run方法,此方法源码很简单,就是调用传入的Runnable任务的run方法。

3、interrupt,interrupted,isInterrupted方法探究。

测试interrupt,interrupted,isInterrupted
执行结果

          我们可以看到,interrupt方法将线程标记为了中断,这只是状态上发生了变化,实际线程并没有停止,还是正常的被执行了,所以中断不等于线程停止,它只是一个标记了一个线程状态。我们也看到了isInterrupted可以获取到线程中断状态,interrupted也可以获得线程的中断状态,只不过它知道线程的状态是中断时会清除这个状态。

我们从运行结果来看,interrupt对线程只是做了中断标记,事实上什么也没干啊。那它有什么意义。别急我们再把这个方法改造下:


可以看到,如果线程被中断了,尝试调用线程的sleep方法会触发中断异常。触发中断异常后,会清除线程的中断状态。当然并不单单sleep方法会触发。join方法和wait方法都会产生这样的效果。

知道了它我们可以针对灵活的作出设计。尤其在线程之间协作时。

4、join方法探究:


从结果来看,任务一完成需要6秒钟,为什么是6秒而不是7秒,说明了任务2和任务1同时执行了1秒钟。任务一等任务2,用了4秒钟。

我们再来修改下任务一:

分析一下:任务一执行用4秒,其中两秒是用在了等待任务二执行。但是任务二在等待了两秒后并没有执行完成。所以等1执行完成后,二才执行完成。

线程的方法稍微难理解的就这几个,其他的都很容易理解,而且在演示代码中也都用了下,如果感兴趣,可自行尝试。

你可能感兴趣的:(迈向Java高级程序员(二)-----先从并发开始(线程篇))