- 尽管多线程启动时是有顺序的(通常是for循环),但真正运行起来后,其实没有完全的先后顺序
起10个线程 |
看执行: thread-1:a:10 thread-1:b:3 thread-4:a:11 thread-4:b:3 thread-6:a:12 thread-6:b:7 |
- 基础的多线程————基于语句,无序竞争
|
执行结果: 发现各线程的方法很难完整从到尾一气呵成的执行,证明多线程是基于语句的而不是基于方法的 [INFO ] 2010-05-21 17:10:05,312 thread-0 start to a++ [INFO ] 2010-05-21 17:10:05,312 thread-9 start to a++ [INFO ] 2010-05-21 17:10:05,312 thread-9 a++ finihed [INFO ] 2010-05-21 17:10:05,312 thread-9 start to b++ [INFO ] 2010-05-21 17:10:05,312 thread-9 b++ finished thread-9:a:2 thread-9:b:1 thread-5:b:3 [INFO ] 2010-05-21 17:10:05,328 thread-3 start to a++ [INFO ] 2010-05-21 17:10:05,312 thread-1 start to a++ [INFO ] 2010-05-21 17:10:05,328 thread-1 a++ finihed [INFO ] 2010-05-21 17:10:05,328 thread-1 start to b++ [INFO ] 2010-05-21 17:10:05,328 thread-1 b++ finished thread-1:a:8 thread-1:b:6 [INFO ] 2010-05-21 17:10:05,328 thread-3 a++ finihed [INFO ] 2010-05-21 17:10:05,328 thread-3 start to b++ [INFO ] 2010-05-21 17:10:05,328 thread-3 b++ finished |
- 加了sleep/intercept的多线程: 各线程竞争更合理更有序
|
各线程的语句执行情况大为改观 尽管各线程仍存在竞争,各线程方法仍很难完整执行 但加了sleep/interrupted后,等于增加了调度功能,各线程竞争更合理,更有序 [INFO ] 2010-05-21 17:20:00,593 thread-6 start to a++ [INFO ] 2010-05-21 17:20:00,593 thread-6 a++ finihed [INFO ] 2010-05-21 17:20:00,593 thread-1 start to a++ [INFO ] 2010-05-21 17:20:00,609 thread-1 a++ finihed [INFO ] 2010-05-21 17:20:00,593 thread-4 start to a++ [INFO ] 2010-05-21 17:20:00,593 thread-2 start to a++ [INFO ] 2010-05-21 17:20:00,609 thread-2 a++ finihed [INFO ] 2010-05-21 17:20:00,593 thread-0 start to a++ [INFO ] 2010-05-21 17:20:00,609 thread-3 start to a++ [INFO ] 2010-05-21 17:20:00,609 thread-3 a++ finihed [INFO ] 2010-05-21 17:20:00,609 thread-4 a++ finihed [INFO ] 2010-05-21 17:20:00,609 thread-8 start to a++ [INFO ] 2010-05-21 17:20:00,609 thread-5 start to a++ [INFO ] 2010-05-21 17:20:00,609 thread-5 a++ finihed [INFO ] 2010-05-21 17:20:00,609 thread-0 a++ finihed [INFO ] 2010-05-21 17:20:00,609 thread-7 start to a++ [INFO ] 2010-05-21 17:20:00,609 thread-7 a++ finihed [INFO ] 2010-05-21 17:20:00,609 thread-8 a++ finihed [INFO ] 2010-05-21 17:20:00,609 thread-9 start to a++ [INFO ] 2010-05-21 17:20:00,609 thread-9 a++ finihed [INFO ] 2010-05-21 17:20:00,609 thread-0 start to b++ [INFO ] 2010-05-21 17:20:00,609 thread-0 b++ finished [INFO ] 2010-05-21 17:20:00,609 thread-8 start to b++ [INFO ] 2010-05-21 17:20:00,609 thread-8 b++ finished [INFO ] 2010-05-21 17:20:00,609 thread-2 start to b++ [INFO ] 2010-05-21 17:20:00,609 thread-2 b++ finished [INFO ] 2010-05-21 17:20:00,625 thread-3 start to b++ [INFO ] 2010-05-21 17:20:00,625 thread-3 b++ finished [INFO ] 2010-05-21 17:20:00,640 thread-5 start to b++ [INFO ] 2010-05-21 17:20:00,640 thread-5 b++ finished [INFO ] 2010-05-21 17:20:00,640 thread-1 start to b++ [INFO ] 2010-05-21 17:20:00,640 thread-1 b++ finished thread-3:a:10 thread-3:b:6 [INFO ] 2010-05-21 17:20:00,656 thread-3 start to a++ [INFO ] 2010-05-21 17:20:00,656 thread-3 a++ finihed thread-1:a:11 thread-1:b:6 [INFO ] 2010-05-21 17:20:00,656 thread-1 start to a++ [INFO ] 2010-05-21 17:20:00,656 thread-1 a++ finihed thread-8:a:12 thread-8:b:6 [INFO ] 2010-05-21 17:20:00,671 thread-8 start to a++ [INFO ] 2010-05-21 17:20:00,671 thread-8 a++ finihed thread-0:a:13 thread-0:b:6 [INFO ] 2010-05-21 17:20:00,671 thread-0 start to a++ [INFO ] 2010-05-21 17:20:00,671 thread-0 a++ finihed [INFO ] 2010-05-21 17:20:00,671 thread-9 start to b++ [INFO ] 2010-05-21 17:20:00,671 thread-9 b++ finished [INFO ] 2010-05-21 17:20:00,671 thread-4 start to b++ [INFO ] 2010-05-21 17:20:00,671 thread-4 b++ finished [INFO ] 2010-05-21 17:20:00,671 thread-3 start to b++ [INFO ] 2010-05-21 17:20:00,671 thread-3 b++ finished thread-4:a:14 thread-4:b:9 [INFO ] 2010-05-21 17:20:00,671 thread-4 start to a++ [INFO ] 2010-05-21 17:20:00,671 thread-4 a++ finihed [INFO ] 2010-05-21 17:20:00,687 thread-7 start to b++ [INFO ] 2010-05-21 17:20:00,687 thread-7 b++ finished [INFO ] 2010-05-21 17:20:00,687 thread-6 start to b++ [INFO ] 2010-05-21 17:20:00,687 thread-6 b++ finished thread-2:a:15 thread-2:b:11 [INFO ] 2010-05-21 17:20:00,703 thread-2 start to a++ [INFO ] 2010-05-21 17:20:00,703 thread-2 a++ finihed [INFO ] 2010-05-21 17:20:00,703 thread-1 start to b++ [INFO ] 2010-05-21 17:20:00,703 thread-1 b++ finished [INFO ] 2010-05-21 17:20:00,718 thread-0 start to b++ [INFO ] 2010-05-21 17:20:00,718 thread-0 b++ finished [INFO ] 2010-05-21 17:20:00,718 thread-2 start to b++ [INFO ] 2010-05-21 17:20:00,718 thread-2 b++ finished |
- 线程加了优先级 , 执行更有序
class Thread的静态属性: static int MAX_PRIORITY static int MIN_PRIORITY static int NORM_PRIORITY ** Thread.MAX_PRIORITY = 10 ** Thread.NORM_PRIORITY = 5 ** Thread.MIN_PRIORITY = 1 主方法main()的优先级是NORM_PRIORITY |
|
运行: D:\java\source\thread\test1>java prioritydemo.PriorityDemo01 线程A线程正在运行。 线程C线程正在运行。 线程B线程正在运行。 线程C线程正在运行。 线程A线程正在运行。 线程B线程正在运行。 线程C线程正在运行。 线程A线程正在运行。 线程B线程正在运行。 线程C线程正在运行。 线程A线程正在运行。 线程B线程正在运行。 线程C线程正在运行。 线程A线程正在运行。 线程B线程正在运行。 线程C线程正在运行。 线程A线程正在运行。 |
- 同步方法
|
doWrite()已经可以完整执行了,尽管它仍容易被打断,但只会被其他方法打断,不会被其它线程的doWrite()方法打断 方法执行被打断是肯定了,因为线程是基于语句的,不是基于方法的 synchronized是阻止别的线程同一时刻调用本方法,而不是阻止别的线程的别的方法(不是本方法)打断本方法 [INFO ] 2010-05-21 17:48:34,343 thread-0 start to a++ [INFO ] 2010-05-21 17:48:34,343 thread-0 a++ finihed [INFO ] 2010-05-21 17:48:34,390 thread-0 start to b++ [INFO ] 2010-05-21 17:48:34,390 thread-0 b++ finished thread-0:a:1 [INFO ] 2010-05-21 17:48:34,421 thread-8 start to a++ [INFO ] 2010-05-21 17:48:34,421 thread-8 a++ finihed thread-0:b:1 [INFO ] 2010-05-21 17:48:34,515 thread-8 start to b++ [INFO ] 2010-05-21 17:48:34,515 thread-8 b++ finished thread-8:a:2 thread-8:b:2 [INFO ] 2010-05-21 17:48:34,546 thread-6 start to a++ [INFO ] 2010-05-21 17:48:34,546 thread-6 a++ finihed [INFO ] 2010-05-21 17:48:34,609 thread-6 start to b++ [INFO ] 2010-05-21 17:48:34,609 thread-6 b++ finished thread-6:a:3 thread-6:b:3 [INFO ] 2010-05-21 17:48:34,703 thread-4 start to a++ [INFO ] 2010-05-21 17:48:34,703 thread-4 a++ finihed [INFO ] 2010-05-21 17:48:34,765 thread-4 start to b++ [INFO ] 2010-05-21 17:48:34,765 thread-4 b++ finished thread-4:a:4 thread-4:b:4 [INFO ] 2010-05-21 17:48:34,859 thread-2 start to a++ [INFO ] 2010-05-21 17:48:34,859 thread-2 a++ finihed [INFO ] 2010-05-21 17:48:34,937 thread-2 start to b++ [INFO ] 2010-05-21 17:48:34,937 thread-2 b++ finished thread-2:a:5 thread-2:b:5 [INFO ] 2010-05-21 17:48:35,031 thread-9 start to a++ [INFO ] 2010-05-21 17:48:35,031 thread-9 a++ finihed [INFO ] 2010-05-21 17:48:35,109 thread-9 start to b++ [INFO ] 2010-05-21 17:48:35,109 thread-9 b++ finished |
如果没有加sleep/interrupted语句,doWrite就很难被print()打断,因为print()在run()方法里是在doWrite()之后执行的。
而doWrite()因为synchronized,实际上被阻塞住了,等于别的线程都阻塞在doWrite(),自然也不执行后边的print()
当然这样一来效率就很低了,同步方法效率都会很低, 因为它阻塞的是别的线程对方法的调用,通常采用的都是同步代码块.
- 完整的"不被打断"
|
1。每个方法都不会被其他线程的"同名"方法打断 2。但每个方法可能被其他线程的"非同名"方法打断 [INFO ] 2010-05-21 18:22:27,718 thread-0 start to a++ [INFO ] 2010-05-21 18:22:27,718 thread-0 a++ finihed [INFO ] 2010-05-21 18:22:27,718 thread-0 start to b++ [INFO ] 2010-05-21 18:22:27,718 thread-0 b++ finished [INFO ] 2010-05-21 18:22:27,718 thread-7 start to a++ [INFO ] 2010-05-21 18:22:27,718 thread-7 a++ finihed [INFO ] 2010-05-21 18:22:27,718 thread-7 start to b++ [INFO ] 2010-05-21 18:22:27,718 thread-7 b++ finished [INFO ] 2010-05-21 18:22:27,718 thread-9 start to a++ [INFO ] 2010-05-21 18:22:27,718 thread-9 a++ finihed [INFO ] 2010-05-21 18:22:27,718 thread-9 start to b++ [INFO ] 2010-05-21 18:22:27,718 thread-9 b++ finished thread-9:a:3 thread-9:b:3 [INFO ] 2010-05-21 18:22:27,718 thread-9 start to a++ [INFO ] 2010-05-21 18:22:27,718 thread-9 a++ finihed [INFO ] 2010-05-21 18:22:27,718 thread-9 start to b++ [INFO ] 2010-05-21 18:22:27,718 thread-9 b++ finished thread-9:a:4 thread-9:b:4 [INFO ] 2010-05-21 18:22:27,718 thread-9 start to a++ [INFO ] 2010-05-21 18:22:27,718 thread-9 a++ finihed [INFO ] 2010-05-21 18:22:27,718 thread-9 start to b++ [INFO ] 2010-05-21 18:22:27,718 thread-9 b++ finished |
- 极端的"不被打断" ----连"被其他线程非同名方法打断"的情况都禁止掉
|
这样其实已经不是”并发“了,只有一个线程run方法全部执行完,其他线程run()才开始执行,实际上成了”顺序“执行 [INFO ] 2010-05-21 18:26:10,906 thread-0 start to a++ [INFO ] 2010-05-21 18:26:10,906 thread-0 a++ finihed [INFO ] 2010-05-21 18:26:10,906 thread-0 start to b++ [INFO ] 2010-05-21 18:26:10,906 thread-0 b++ finished thread-0:a:1 thread-0:b:1 [INFO ] 2010-05-21 18:26:10,906 thread-0 start to a++ [INFO ] 2010-05-21 18:26:10,906 thread-0 a++ finihed [INFO ] 2010-05-21 18:26:10,921 thread-0 start to b++ [INFO ] 2010-05-21 18:26:10,921 thread-0 b++ finished thread-0:a:2 thread-0:b:2 [INFO ] 2010-05-21 18:26:10,921 thread-0 start to a++ [INFO ] 2010-05-21 18:26:10,921 thread-0 a++ finihed [INFO ] 2010-05-21 18:26:10,921 thread-0 start to b++ [INFO ] 2010-05-21 18:26:10,921 thread-0 b++ finished thread-0:a:3 thread-0:b:3 [INFO ] 2010-05-21 18:26:10,921 thread-0 start to a++ [INFO ] 2010-05-21 18:26:10,921 thread-0 a++ finihed [INFO ] 2010-05-21 18:26:10,921 thread-0 start to b++ [INFO ] 2010-05-21 18:26:10,921 thread-0 b++ finished thread-0:a:4 thread-0:b:4 [INFO ] 2010-05-21 18:26:10,921 thread-0 start to a++ [INFO ] 2010-05-21 18:26:10,921 thread-0 a++ finihed [INFO ] 2010-05-21 18:26:10,921 thread-0 start to b++ [INFO ] 2010-05-21 18:26:10,921 thread-0 b++ finished thread-0:a:5 thread-0:b:5 [INFO ] 2010-05-21 18:26:10,921 thread-0 start to a++ [INFO ] 2010-05-21 18:26:10,921 thread-0 a++ finihed [INFO ] 2010-05-21 18:26:10,921 thread-0 start to b++ [INFO ] 2010-05-21 18:26:10,921 thread-0 b++ finished thread-0:a:6 thread-0:b:6 |
- join()方法——————让线程真正按启动顺序执行,必须等start()的运行完成后才继续运行后面的语句, 也是一种"顺序"执行
假设线程MyThread的功能是打印0-99
public class Test { public static void main(String[] args) throws Exception{ MyThread mt = new MyThread(); mt.start(); } } |
输出其实是: 101,0,...99 |
public class Test { public static void main(String[] args) throws Exception{ MyThread mt = new MyThread(); mt.start(); mt.join(); System.out.println(101); } } |
输出: 0,...99,101 |