java(七) ——多线程
2022/1/24 22:05:41
本文主要是介绍java(七) ——多线程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1.jvm与多线程
jvm里分为方法区、虚拟机栈、本地方法栈、堆、程序计数器
每个进程在方法区与堆里有一份
每个线程在虚拟机栈与程序计数器里有一份
2.java程序中自带的线程
一个java.exe程序中,至少存在三个线程:主线程、垃圾回收线程、异常处理线程
3.创建线程方式一:继承Thread类
/** * @author ym * @create 2022-01-24 17:38 * @description 测试创建线程的方法,即继承thread类 得到100以内的所有偶数 */ public class ThreadTest extends Thread { @Override public void run() { for (int i = 0; i < 1001; i++) { if (i % 2 == 0) { System.out.println(i); } } } }
/** * @author ym * @create 2022-01-24 17:40 * @description */ public class ThreadTest1 { public static void main(String[] args) { ThreadTest threadTest = new ThreadTest(); threadTest.start(); for (int i = 0; i < 1001; i++) { if (i % 2 == 0) { System.out.println("main"); } } } }
注意:
1.不能用直接调用run方法的方式开启线程,这样的话只是相当于普通的函数调用,并没有打开新的线程
2.不能再调用一个start()过了的线程对象的start()方法
4.线程中常用方法
/** * @author ym * @create 2022-01-24 17:40 * @description */ public class ThreadTest1 { /** * 线程中常用方法: * 1.start():启动当前线程,调用当前线程的run()方法 * 2.run():重写Thread类中的此方法,将创建的线程要执行的内容声明在此处 * 3.currentThread():静态方法,返回执行当前代码的线程 * 4.getName():获取当前线程的名字 * 5.setName():设置当前线程的名字 * 6.yield():释放当前cpu的执行权 * 7.join():在a线程中调用b线程的join()方法,则a线程会一直阻塞到b线程完全执行结束 * 8.stop():已过时,当执行此方法时,强制结束当前线程 * 9.sleep(long milltime):休眠,休眠期间当前线程是阻塞状态 * 10.isAlive():判断当前线程是否存活 * * @param args */ public static void main(String[] args) throws InterruptedException { ThreadTest threadTest = new ThreadTest(); // 5.setName():设置当前线程的名字 Thread.currentThread().setName("主线程ym"); //1.start():启动当前线程,调用当前线程的run()方法 threadTest.start(); for (int i = 0; i < 1001; i++) { if (i % 2 == 0) { // 3.currentThread():静态方法,返回执行当前代码的线程 //4.getName():获取当前线程的名字 System.out.println(Thread.currentThread().getName() + "main\t" + i); } if (i == 800) { // 7.join():在a线程中调用b线程的join()方法,则a线程会一直阻塞到b线程完全执行结束 threadTest.join(); } if (i == 900) { // 8.stop():已过时,当执行此方法时,强制结束当前线程 Thread.currentThread().stop(); } } } }
/** * @author ym * @create 2022-01-24 17:38 * @description 测试创建线程的方法,即继承thread类 得到100以内的所有偶数 */ public class ThreadTest extends Thread { //2.run():重写Thread类中的此方法,将创建的线程要执行的内容声明在此处 @Override public void run() { // 5.setName():设置当前线程的名字 setName("测试线程ym"); for (int i = 0; i < 1001; i++) { if (i % 2 == 0) { //3.currentThread():静态方法,返回执行当前代码的线程 //4.getName():获取当前线程的名字 System.out.println(currentThread().getName() + i); } if (i == 700) { try { // 9.sleep(long milltime):休眠,休眠期间当前线程是阻塞状态 sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } if (i == 850) { // 10.isAlive():判断当前线程是否存活 System.out.println(isAlive()); } if (i % 10 == 0) { // 6.yield():释放当前cpu的执行权 yield(); } } } }
5.创建线程的第二个方法:实现runnable接口
/** * @author ym * @create 2022-01-24 20:36 * @description 第二种创建线程的方式,实现runnable接口 */ public class ThreadTest2 { public static void main(String[] args) { MyThread myThread = new MyThread(); Thread thread = new Thread(myThread); thread.start(); Thread thread1 = new Thread(myThread); thread1.start(); } } class MyThread implements Runnable { /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object's * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see Thread#run() */ @Override public void run() { for (int i = 0; i < 100; i++) { if (i % 2 == 0) { System.out.println(i + "\t" + Thread.currentThread().getName()); } } } }
6.常见多线程初识问题:窗口卖票问题
需求:3个窗口共卖出100张票
实现方案1:用继承thread的方式,不过此时需注意,票数需要static
package com.exer; /** * @author ym * @create 2022-01-24 20:12 * @description 三个窗口卖票问题 */ public class TicketDemo { public static int tickets = 100; public static void main(String[] args) { TicketSell ticketSell1 = new TicketSell(); TicketSell ticketSell2 = new TicketSell(); TicketSell ticketSell3 = new TicketSell(); ticketSell1.start(); ticketSell2.start(); ticketSell3.start(); } } class TicketSell extends Thread{ @Override public void run() { while (true){ if (TicketDemo.tickets>0){ TicketDemo.tickets--; System.out.println(TicketDemo.tickets+"\t"+getName()); }else { break; } } } }
**实现方案2:用实现runnable接口的方式,此时便不需将票数static了,因为每个线程都共用一个实现了runnable的线程操作对象 **
package com.exer; /** * @author ym * @create 2022-01-24 20:45 * @description */ public class TicketDemo1 { public static void main(String[] args) { MyThread myThread = new MyThread(); Thread thread1 = new Thread(myThread); Thread thread2 = new Thread(myThread); Thread thread3 = new Thread(myThread); thread1.start(); thread2.start(); thread3.start(); } } class MyThread implements Runnable { public int tickets = 100; /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object's * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see Thread#run() */ @Override public void run() { while (true) { if (tickets > 0) { tickets--; System.out.println(Thread.currentThread().getName() + "\t" + tickets); } else { break; } } } }
7.总结:在开发中,多线程创建尽量使用实现runnable()接口的方法,原因:
1.实现的方式没有类的单继承性的局限
2。实现的方式更适合来处理多个线程有共享数据的情况
这篇关于java(七) ——多线程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)