jvm里分为方法区、虚拟机栈、本地方法栈、堆、程序计数器
每个进程在方法区与堆里有一份
每个线程在虚拟机栈与程序计数器里有一份
一个java.exe程序中,至少存在三个线程:主线程、垃圾回收线程、异常处理线程
/** * @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()方法
/** * @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(); } } } }
/** * @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()); } } } }
需求: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; } } } }
1.实现的方式没有类的单继承性的局限
2。实现的方式更适合来处理多个线程有共享数据的情况