当前位置: 首页 > news >正文

c语言开发网站教程/长春网站提升排名

c语言开发网站教程,长春网站提升排名,梅江区住房和城乡建设局官方网站,改版网站收费我们都知道.start()可以启动多线程,使线程进入就绪状态,但是不一定会立即执行。 以下的代码,如果别人问你是A线程先启动,还是B线程先启动,那就要注意他说的启动是什么含义。因为start翻译成中文就是启动。.start()也叫…

我们都知道.start()可以启动多线程,使线程进入就绪状态,但是不一定会立即执行。

以下的代码,如果别人问你是A线程先启动,还是B线程先启动,那就要注意他说的启动是什么含义。因为start翻译成中文就是启动。.start()也叫启动线程

A线程先启动,还是B线程先启动?
答案有两个:但说的都是同一件事
答案1:代码从上往下执行的,A线程先启动(指先调用了.start()方法),B线程再启动(后调用.start()方法),但AB线程中的run方法的执行顺序是不确定的,可能A先,可能B先
答案2.随机的,可能A先启动,可能B先(这个启动指的就是run方法的调用了)
在这里插入图片描述
大部分人说的启动都是第二种意思:指的是run方法的调用。
我个人偏向第一种解释:把线程的启动和执行概念分开比较好。
.start()方法调用表示启动线程,进入就绪状态。线程具体什么时候执行,不确定。

结论:
多线程的创建/启动是按顺序执行的,主线程会从上往下执行。
多线程的执行顺序是不确定的,谁抢到谁执行

代码验证,循环启动10个线程,每个线程输出当前线程的名字,这里我取了个巧,将i的值设置成当前线程的名字

public class Test {public static void main(String[] args) throws InterruptedException {int i;for (i = 1; i <= 10; i++) {new Thread(() -> {System.out.println(Thread.currentThread().getName());}, String.valueOf(i)).start();System.out.println("此线程已启动,当前线程是" + i);}}
}

虽然每次输出结果都不一样,但万变不离其宗,结论都是一样的:

  • 多线程的启动是按顺序执行的,主线程会从上往下依次启动线程
  • 虽然多线程的执行顺序是不确定的,但有一点可以确定:线程要先启动后才有机会执行。换句话说,当cpu从main线程切换到其他线程时,会在已启动的线程中,随机抽一个线程来执行。线程要是启动的慢,肯定轮不到你来执行。
此线程已启动,当前线程是1
1
此线程已启动,当前线程是2
此线程已启动,当前线程是3
此线程已启动,当前线程是4
3
2
此线程已启动,当前线程是5
此线程已启动,当前线程是6
此线程已启动,当前线程是7
4
此线程已启动,当前线程是8
5
此线程已启动,当前线程是9
此线程已启动,当前线程是10
6
7
9
10
8Process finished with exit code 0

解释清楚很简单,线程有五个状态:新建、就绪、运行、阻塞、死亡.

  • new Thread(),该线程就是新建状态。创建线程和启动线程都是顺序执行的,未创建的线程当然没有资格去抢cpu执行权。
  • .start()方法使线程进入就绪状态,这个线程有资格执行。就绪状态中的线程去抢cpu执行权,获取到cpu执行权后,线程进入运行状态,开始调用自己的run方法。

看的更明显一点:

public class Test {public static void main(String[] args) throws InterruptedException {int i;for (i = 1; i <= 10; i++) {System.out.println("main线程:准备创建线程" + i);new Thread(() -> {System.out.println("main线程已切换到其余线程:"+Thread.currentThread().getName()+"已抢到cpu执行权");}, String.valueOf(i)).start();System.out.println("main线程:"+i+"线程已创建,"+i+"线程进入就绪状态");}System.out.println("main线程执行完毕");}
}

main线程准备创建线程4时,还没创建就被打断了。就绪状态的线程中有1,2,3。线程1抢到cpu执行权。4-10线程此时还没创建呢,抢的资格都没有。
这个例子也说明了,如果有其他线程进入就绪状态,main线程随时都有可能被打断

main线程:准备创建线程1
main线程:1线程已创建,1线程进入就绪状态
main线程:准备创建线程2
main线程:2线程已创建,2线程进入就绪状态
main线程:准备创建线程3
main线程:3线程已创建,3线程进入就绪状态
*main线程:准备创建线程4 ####注意这行
已切换到其余线程:1已抢到cpu执行权
main线程:4线程已创建,4线程进入就绪状态
main线程:准备创建线程5
main线程:5线程已创建,5线程进入就绪状态
main线程:准备创建线程6
main线程:6线程已创建,6线程进入就绪状态
main线程:准备创建线程7
main线程:7线程已创建,7线程进入就绪状态
main线程:准备创建线程8
main线程:8线程已创建,8线程进入就绪状态
main线程:准备创建线程9
已切换到其余线程:2已抢到cpu执行权
已切换到其余线程:3已抢到cpu执行权
main线程:9线程已创建,9线程进入就绪状态
main线程:准备创建线程10
main线程:10线程已创建,10线程进入就绪状态
main线程执行完毕
已切换到其余线程:4已抢到cpu执行权
已切换到其余线程:5已抢到cpu执行权
已切换到其余线程:6已抢到cpu执行权
已切换到其余线程:8已抢到cpu执行权
已切换到其余线程:7已抢到cpu执行权
已切换到其余线程:10已抢到cpu执行权
已切换到其余线程:9已抢到cpu执行权
Process finished with exit code 0
  • 写代码会经常看到一种现象。先启动的线程大概率会先执行。
  • 多线程的执行顺序是不确定的,随机的,谁抢到谁执行,这句话是有前提的。前提是这10个线程都已经进入就绪状态了,大家都在同一起跑线上,那么抢cpu执行权就是随机抢的。
  • 但也有可能别的线程还没创建或者还没启动时,你就已经先启动先进入就绪状态,此时其他线程还没就绪状态,无法跟你抢cpu执行权,近水楼台先得月。大家都不在同一起跑线上,随机那也只是进入就绪状态中的线程中随机。遇到这种现象,明白就好。

应该解释的很清楚了。

多线程之间按顺序调用

来自b站视频尚硅谷周阳老师-juc
前面提到,多线程之间是随机调用的。可以顺序调用吗?其实也是可以的。

/*** 多线程之间按顺序调用,实现A->B->C* 三个线程启动,要求如下:* AA打印5次,BB打印10次,CC打15次* AA打印5次,BB打印10次,CC打15次* 重复以上过程来10轮** 1.高聚低合前提下,线程操作资源类* 2.判断/干活/通知* 3.多线程交互中,必须要防止多线程的虚假唤醒,也即(判断只用while,不能用if)* 4.标志位*/

如何实现A->B->C?思路很简单,最开始只允许A线程进入,BC线程即使进入也得等着。然后A精准唤醒B,B精准唤醒C

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;class ShareSource {private int number=1;   //1:A 2:B 3:Cprivate Lock lock=new ReentrantLock();private Condition condition=lock.newCondition();  //类似钥匙private Condition condition2=lock.newCondition();private Condition condition3=lock.newCondition();Condition[] conditions={condition,condition2,condition3};//功能都在资源类上,体现了高内聚public void print(int x){lock.lock();try {//判断while (number!=x){   //number初始值是1//有三个线程,谁等?这里需要思考一下//一开始,1!=1,只有A线程能进来干活,BC线程进来就等着。System.out.println("等待并释放锁的索引:"+(x-1));conditions[x-1].await();}//干活for (int i = 1; i <=number*5; i++) {System.out.println(Thread.currentThread().getName()+"\t"+i);}//通知number++;if (number > 3) {number=1;    //123123循环x}conditions[number-1].signal();   //A线程精准唤醒B线程,B线程钥匙的数组索引是1}catch (Exception e){e.getStackTrace();}finally {System.out.println((x-1)+"的索引释放了锁");lock.unlock();}}
}/*** 多线程之间按顺序调用,实现A->B->C* 三个线程启动,要求如下:* AA打印5次,BB打印10次,CC打15次* AA打印5次,BB打印10次,CC打15次* 重复以上过程来10轮** 1.高聚低合前提下,线程操作资源类* 2.判断/干活/通知* 3.多线程交互中,必须要防止多线程的虚假唤醒,也即(判断只用while,不能用if)* 4.标志位*/public class ThreadOrderAccess {public static void main(String[] args) throws InterruptedException {ShareSource shareSource = new ShareSource();new Thread(() -> {for (int i = 1; i <=10 ; i++) {shareSource.print(1);}}, "AA").start();new Thread(() -> {for (int i = 1; i <=10 ; i++) {shareSource.print(2);}}, "BB").start();new Thread(() -> {for (int i = 1; i <=10 ; i++) {shareSource.print(3);}}, "CC").start();}
}

以上把打印方法写在了一起,更简单的写法是print方法写成三个

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;class ShareSource {private int number=1;   //1:A 2:B 3:Cprivate Lock lock=new ReentrantLock();private Condition condition=lock.newCondition();  //类似钥匙,一把锁三把钥匙private Condition condition2=lock.newCondition();private Condition condition3=lock.newCondition();public void print5(){lock.lock();try {while (number != 1) {//如果number!= 1,说明不是A系统干活condition.await();}for (int i = 1; i <=5 ; i++) {System.out.println(Thread.currentThread().getName()+"\t"+i);}number=2;//A线程通知B线程condition2.signal();}catch (Exception e){e.getStackTrace();}finally {lock.unlock();}}public void print10(){lock.lock();try {while (number != 2) {//如果number!= 2,说明不是B系统干活condition2.await();}for (int i = 1; i <=10 ; i++) {System.out.println(Thread.currentThread().getName()+"\t"+i);}number=3;condition3.signal();}catch (Exception e){e.getStackTrace();}finally {lock.unlock();}}public void print15(){lock.lock();try {while (number != 3) {//如果number!= 3,说明不是C系统干活condition3.await();}for (int i = 1; i <=15 ; i++) {System.out.println(Thread.currentThread().getName()+"\t"+i);}number=1;condition.signal();}catch (Exception e){e.getStackTrace();}finally {lock.unlock();}}
}public class ThreadOrderAccess2 {public static void main(String[] args) throws InterruptedException {ShareSource shareSource = new ShareSource();new Thread(() -> {for (int i = 1; i <=10 ; i++) {shareSource.print5();}}, "A").start();new Thread(() -> {for (int i = 1; i <=10 ; i++) {shareSource.print10();}}, "B").start();new Thread(() -> {for (int i = 1; i <=10 ; i++) {shareSource.print15();}}, "C").start();}
}
http://www.jmfq.cn/news/4870531.html

相关文章:

  • 我有网网站建设/漂亮的网页设计
  • 智能网站建设哪家好/旅游企业seo官网分析报告
  • 最好大连网站建设/郑州百度推广哪家好
  • 四川 优质高职建设网站/搜索引擎优化的报告
  • 电子商务网站规划原则/免费二级域名分发
  • pc网站建设需要提供哪些资料/百度seo关键词排名s
  • 部门将网站建设的需求/怎样制作一个网站
  • 张家口建设网站/长沙本地推广联系电话
  • 网站做强制访问控制/seo网站推广与优化方案
  • 手机论坛网站模板/搜外友链平台
  • 网站开发设计/百度推广工具有哪些
  • 咸阳网站建设seo/最近新闻报道
  • 什么是网站镜像/国家免费培训学校
  • 安能建设总公司网站打不开/网络营销主要干什么
  • 网站开发实战项目/网络推广公司有多少家
  • 外贸公司网站如何做推广/市场营销的八个理论
  • 抖音代运营协议/李江seo
  • 中国人做代购的网站/郑州seo技术
  • 免费网站建设自带后台管理程序/重庆seo入门教程
  • 2012年dede红色政府网站模板/怎么找拉新推广平台
  • 网站风格的设计/百度客服电话人工服务
  • 网站建设综合实训设计报告/黄山网络推广公司
  • 小型教育网站的开发与建设/关键词优化哪家强
  • wordpress改颜色/优化营商环境工作总结
  • 海口seo整站/软文营销范文100字
  • 中国建设银行属于什么类型网站/seo推广思路
  • 自己做网站可以挣钱吗/产品营销策略
  • 网站因该怎么做参考文献/企业网站推广的方法有
  • 科技企业网站建设/厦门seo测试
  • 郑州网络推广专员/数字营销服务商seo