Java 多线程基本概念
进程:是正在运行的程序
线程:是进程中单个顺序控制流,是一条执行路径
创建线程的方法
方式1.继承Thread类
1.定义一个继承Thread的类
2.在该类中重写run()方法
3.在main中创建该类的对象
4.启动线程start //注意:只调用run方法并不会启动线程
//JVM:即java虚拟机
代码示例:
代码示例:
补充:
join()方法指让调用该方法的线程强制优先执行完毕直到死亡后其他线程才可继续执行
线程.setDaemon(true)方法里面为true
补充yield()方法:
线程的生命周期(理解)
代码示例:
//注Runnable接口的一些方法与Thread类并不相同,如getName()的使用形式就不同
案例:解决多条语句同时操作共享数据导致买票程序出现同一张票被卖多次问题
利用wait()和notify()函数线程进行交替输出操作:
//例:使三个线程交替输出“AA”“BB”“CC”
package step1; public class Task { public static void main(String[] args) throws Exception { /********* Begin *********/ //在这里创建线程, 开启线程 Object a = new Object(); Object b = new Object(); Object c = new Object(); MyThread t1 = new MyThread("AA",c,a); MyThread t2 = new MyThread("BB",a,b); MyThread t3 = new MyThread("CC",b,c); t1.start(); t1.sleep(100);//保证线程按照顺序进行 t2.start(); t2.sleep(100); t3.start(); t3.sleep(100); /********* End *********/ } } class MyThread extends Thread { /********* Begin *********/ String threadName; private Object prev;//输出顺序的前一个对象 private Object self;//自身的输出对象 public MyThread(String Name,Object prev,Object self) { // TODO Auto-generated constructor stub threadName=Name; this.prev=prev; this.self=self; } public void run() { int count = 5; while(count > 0){ synchronized(prev) { synchronized (self) { System.out.println("Java Thread" + this.threadName); count--; self.notify(); } try { prev.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } System.exit(0);//退出jvm } /********* End *********/ }
代码示例:
以此来解决线程安全问题(如多卖票,卖负票的问题)
并发编程的三个概念
在我们进行应用开发的时候,常常会关注网站的并发,如果网站的用户量很多,当这些用户同时访问一个服务的时候,我们的服务器就会接收到大量的并发请求,处理好这些并发请求是一个合格程序员必须要完成的工作。
理解并发编程的三个概念对于我们更好的开发高并发的Web
应用有很大的帮助。
1.原子性:即一个操作或者多个操作,要么全部执行并且在执行过程中不会被任何因素打断,要么就不执行。只有简单的读取,赋值(必须是将数字赋值给某个变量,变量之间的赋值不是原子性操作),才是原子性操作。synchronized
和lock
可以保证在任何时候只有一个线程执行该代码块,所以就保证了原子性。
2.可见性:可见性是当多个线程访问一个变量时,一个线程改变了变量的值,其他线程立马可以知道这个改变。关于保证可见性还可以通过Synchronized
和lock
的方式来实现。
例:使用volatile实现变量的可见性,参考:https://www.educoder.net/tasks/eauswpqzrm9h
3.有序性:即程序的执行是按照代码编写的先后顺序执行的。程序可能会发生指令重排序,即处理器为了提升执行效率,会对输入代码进行优化,它不保证代码执行的顺序和代码编写的顺序一致,但是它会保证程序的输出结果和代码的顺序执行结果是一致的。
有序性的例子:
也就是说,要保证多线程程序执行的正确性,必须要保证原子性、可见性以及有序性。只要有一个没有被保证,就有可能会导致程序运行不正确。
Java多线程实训习题:https://www.educoder.net/classrooms/4909/shixun_homeworks/65354
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗