/**
多线程:多个线程同时执行,会抢占资源(案例:迅雷的多个下载任务)
进程:运行时的程序称为进程,它由多个不同的线程组成
线程原理:程序的一个顺序控制流程,也是CPU的基本调度单位
线程组成:由CPU时间片、运行数据、线程的逻辑代码组成
CPU时间片:会为每个线程分配执行时间
运行数据:分为堆空间和栈空间:堆空间储存对象,栈空间储存局部变量
*/
//1、简单多线程
1 public class ThreadTest { 2 public static void main(String[] args) { 3 MyThread mt1 = new MyThread(); 4 MyRunnable mr2 = new MyRunnable(); 5 //调用start()方法:作用是启动一个新线程,处于就绪(可运行)状态,获取到CPU时间片即可运行 6 mt1.start(); 7 mr2.run(); 8 } 9 } 10 class MyThread extends Thread{ 11 public void run(){ 12 for (int i = 0; i <100 ; i++) { 13 System.out.println("MyThread线程启动:"+i+"次"); 14 } 15 } 16 } 17 class MyRunnable extends Thread{ 18 public void run(){ 19 for (int i = 0; i <100 ; i++) { 20 System.out.println("MyRunnable线程启动:"+i+"次"); 21 } 22 } 23 }
/*
线程状态:共有四种,分别为 初始(new)、就绪(runnable)、运行(running)、终止(Terminated)。
1、新建状态:当创建一个线程时,此线程进入新建状态,但此时还未启动。
2、就绪状态:创建好线程后调用线程的start()方法,该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权。等待期间线程处于就绪状态
3、运行状态:当线程获得cpu的使用权后,线程进入运行状态,开始执行run()方法。
4、终止状态:线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。
*/
/**
线程安全问题:在多线程下有可能出现多个线程先后更改数据的情况;单线程天生线程安全。
解决方案:需要为线程加锁
锁:
1)synchronized:用来控制线程同步,保证在多线程环境下,不被多个线程同时执行,确保数据的完整性。
2)Lock:在需要的时候可以手动的获取锁和释放锁,还可以中断获取以及超时获取。
*/
//3、简单多线程锁
1 class TicketLock { 2 private AtomicInteger serviceNum = new AtomicInteger(); // 服务号 3 private AtomicInteger ticketNum = new AtomicInteger(); // 排队号 4 public int lock() { 5 // 首先获得一个排队号 6 int myTicketNum = ticketNum.getAndIncrement(); 7 // 循环判断,拿class TicketLock { 8 private AtomicInteger serviceNum = new AtomicInteger(); // 服务号 9 private AtomicInteger ticketNum = new AtomicInteger(); // 排队号 10 public int lock() { 11 // 首先获得一个排队号 12 int myTicketNum = ticketNum.getAndIncrement(); 13 // 循环判断,拿到直到服务号为止 14 while (serviceNum.get() != myTicketNum) { 15 } 16 return myTicketNum; 17 } 18 public void unlock(int myTicket) { 19 // 只有当前线程拥有者才能释放锁 20 int next = myTicket + 1; 21 serviceNum.compareAndSet(myTicket, next); 22 } 23 } 27 while (serviceNum.get() != myTicketNum) { 28 } 29 return myTicketNum; 30 } 31 public void unlock(int myTicket) { 32 // 只有当前线程拥有者才能释放锁 33 int next = myTicket + 1; 34 serviceNum.compareAndSet(myTicket, next); 35 } 36 }
/**
线程池:线程的容器,在需要线程时才去池中调用,实现重复利用,避免频繁的创建和销毁
线程池接口和类:
1)Executor:线程池的顶级接口
2)ExecutorService:线程池接口,可通过submit提交代码
3)Executors工厂类:通过它可以获取线程池
*/
————————————————
版权声明:本文为CSDN博主「weixin_54533165」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_54533165/article/details/116097070
原文:https://www.cnblogs.com/lqs0823/p/14697475.html