慈溪网站制作哪家最好,百度搜索引擎优化案例,做网站需要几大模板,厦门网站建设团队1. join方法与多线程
1.1 初识多线程 为了提高cpu得利用率#xff0c;因此就引入了多个线程的概念#xff1b;即每个线程负责完成整个程序的一部分工作即可。 写一个代码#xff0c;让主线程#xff0c;创建一个新的线程#xff0c;由新线程负责完成运算#xff08;12。…1. join方法与多线程
1.1 初识多线程 为了提高cpu得利用率因此就引入了多个线程的概念即每个线程负责完成整个程序的一部分工作即可。 写一个代码让主线程创建一个新的线程由新线程负责完成运算12。。。1000最终由主线程负责获取到最终的结果 代码如下 package thread;public class ThreadDemo15 {// t 线程把计算的结果放到 result 中.private static long result 0;public static void main(String[] args) throws InterruptedException {Thread t new Thread(() - {long tmp 0;for (long i 1; i 50_0000L; i) {tmp i;}result tmp;});Thread t2 new Thread(() - {
// try {
// // 如果把 join 加到末尾, 这个时候, 就还是 t 和 t2 并发执行, 没啥区别
// // 如果把 join 加到开头, 这个时候, 就是先执行 t, t2 先阻塞. 等到 t 执行完了之后, t2 继续执行. 又成了串行执行了.
// t.join();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }long tmp 0;for (long i 50_0001L; i 100_0000L; i) {tmp i;}result tmp;});long beg System.currentTimeMillis();t.start();t2.start();// 主要就是不知道 t 线程要执行多久// Thread.sleep(1000);// 使用 join, 就会严格按照 t 线程执行结束来作为等待的条件.// 什么时候 t 运行结束(计算完毕), 什么时候, join 就结束等待// t 运行 1ms, join 就等待 1ms; t 运行 10s, join 就等待 10s// 确保 join 之后得到的结果, 一定是靠谱的结果.t.join();t2.join();long end System.currentTimeMillis();// 上面加上 join 之后, 结果就一定是 t 线程执行结束的结果了.System.out.println(result result);System.out.println(time (end - beg) ms);}
}结果如下 接下来分析t线程t2线程与主线程关于顺序不同而导致的最后执行逻辑的分析 我们预计的线程逻辑是在主线程里面创建t线程和t2线程t线程执行1 ~50000的累计运算和t2线程执行500001~1000000的累计运算的时候主线程处于阻塞状态当两个线程执行结束将最终的计算值给到主线程由主线程进行输出此时我们预计t和t2两个线程是并发执行的因为不能确认t与t2线程何时能够结束所以我们使用join方法让t和t2线程插入到主线程之前当前两者结束之后主线程才恢复到就绪状态前往cpu上执行逻辑 并发并行并发 并行t和t2在两个不同的核心上同时执行 并发t和t2在同一个核心上分时复用 多线程的代码只要稍微改一点结果就会发生很大的变化具体分析如下图所示 1、多线程并发执行 此时是创建两个线程并发执行主线程等待两个线程结束后在执行 2、多线程串行执行 此时是创建一个线程t等待t执行结束后创建线程t1等待t1结束后再执行主线程本质上又是进行串行执行。 1.2 join的多版本 1、join---无参数等待即死等; 2、joinlong millis---带有超时时间的等待即下一个线程等此线程的时间是有限制的 Q:有没有指令能够停止等待 AInterrupt能够把阻塞状态的jion提前唤醒sleep也能被唤醒
1.3 线程的引用 1、如果是继承thread直接使用this拿到线程实例 代码如下 package thread;class MyThread5 extends Thread {Overridepublic void run() {// 这个代码中, 如果想获取到线程的引用, 直接使用 this 即可.System.out.println(this.getId() , this.getName());}
}public class ThreadDemo16 {public static void main(String[] args) throws InterruptedException {MyThread5 t1 new MyThread5();MyThread5 t2 new MyThread5();t1.start();t2.start();Thread.sleep(1000);System.out.println(t1.getId() , t1.getName());System.out.println(t2.getId() , t2.getName());}
}结果如下 如果是runnable或者lambda的方式this就无能为力了这时this已经不指向thread对象了 2、使用Thread.currentThread方法获取当前的线程的引用 代码如下 package thread;public class ThreadDemo17 {public static void main(String[] args) {Thread t1 new Thread(() - {Thread t Thread.currentThread();System.out.println(t.getName());});Thread t2 new Thread(() - {Thread t Thread.currentThread();System.out.println(t.getName());});t1.start();t2.start();}
}结果如下 2. 线程的状态 下面主要向介绍线程在运行中的六种状态 1.NEW Thread对象创建好了但是还没有调用 start 方法在系统中创建线程。 2.TERMINATED Thread 对象仍然存在,但是系统内部的线程已经执行完毕了。 3.RUNNABLE 就绪状态表示这个线程正在 cpu 上执行,或者准备就绪随时可以去 cpu 上执行。 4.TIMED WAITING 指定时间的阻塞.就在到达一定时间之后自动解除阻塞使用 sleep 会进入这个状态 使用带有超时时间的join也会。 5.WAITING 不带时间的阻塞(死等)必须要满足一定的条件,才会解除阻塞join 或者 wait 都会进入 WAITING。 6.BLOCKED 由于锁竞争,引起的阻塞.表示当前的线程是不方便去cpu上执行 这六种状态在整个线程生命周期的大概位置如下图所示 通过代码来得到线程运行时的不同状态如下可得到 NEW 、RUNNABLE、TERMINATED 状态 代码如下 package thread;public class ThreadDemo18 {public static void main(String[] args) throws InterruptedException {Thread t new Thread(() - {for (int i 0; i 5; i) {System.out.println(线程运行中...);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});// 线程启动之前, 状态就是 NEWSystem.out.println(t.getState());t.start();Thread.sleep(500);System.out.println(t.getState());t.join();// 线程运行完毕之后, 状态就是 TERMINATEDSystem.out.println(t.getState());}
}结果如下 注意一个线程只能start一次即当线程的状态只有是NEW状态的线程才能start。 ps本次的内容就到这里了如果对你有帮助的话就请一键三连哦