多线程技术(同步异步,并发并行)守护线程(java垃圾回收机制)
多线程技术概述
每个线程都有自己的栈空间,并用一份堆内存 1.同步和异步
同步:排队执行,效率低但是安全.
异步:同时执行,效率高但是数据不安全. 2.并发与并行
并发:指两个或多个时间在同一个时间段内发生.
并行:指两个或多个时间在同一时刻发生(同时发生) 3.执行步骤,有利于理解线程时用来做什么的 public class Test { public static void main(String[] args) throws InterruptedException { //1.创建一个任务对象 Xiancheng x1 = new Xiancheng(); //2.创建一个线程,并为其分配一个任务 Thread t = new Thread(x1); //3.执行这个线程 t.start(); } } 4.多用Runnable
5.线程对象可以打标记package com.kkb; public class Demo01_ThreadInterrupt { public static void main(String[] args) { Thread t = new Thread(new MyThings()); t.start(); for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName()+i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } t.interrupt();//给线程添加标记 } } class MyThings implements Runnable{ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+i); try { Thread.sleep(1000); } catch (InterruptedException e) {//中断异常-->>如果这个事物正在执行的线程有了中断标记,那么就进入到catch块中 //System.out.println("虽然我添加了标记来到了这里,但是,你没有让我死亡哈哈哈哈"); //加上return资源就释放了 System.out.println("添加了interrupt标记,后面返回return,我结束了"); return; } } } } 6.守护线程
线程:分为守护线程和用户线程
用户线程:当一个进程不包含任何的存货线程时,进程结束
守护线程:守护用户的线程,当最后一个用户线程结束时,所有守护线程自动死亡 package com.kkb; public class Demo01_ThreadInterrupt { public static void main(String[] args) { Thread t = new Thread(new MyThings()); t.setDaemon(true);//设置t为守护线程,当这个应用(进程中最后一个用户线程死亡的时候,守护线程自动死亡) t.start(); for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName()+i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } // t.interrupt();//给线程添加标记 } } class MyThings implements Runnable{ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+i); try { Thread.sleep(1000); } catch (InterruptedException e) {//中断异常-->>如果这个事物正在执行的线程有了中断标记,那么就进入到catch块中 //System.out.println("虽然我添加了标记来到了这里,但是,你没有让我死亡哈哈哈哈"); //加上return资源就释放了 System.out.println("添加了interrupt标记,后面返回return,我结束了"); return; } } } } 7.线程安全问题
概述: * 为什么会导致线程不安全: * 首先假定一种情况:当事物中余票为1时,三个线程进入来买票 * 1.A线程:看到conut>0,进入,正在出票的时候,count还没来得及做数据的变更操作 * 2.B线程:这个时候,B也进来了,因为conut还没有变更 * ..... * 这就是多线程,进入产生时间偏的问题-->>这里为了更好的模拟实际中的放票状态,就引入了一个Thread.sleep,使线程进行休眠的操作package com.kkb; /** * 为什么会导致线程不安全: * 首先假定一种情况:当事物中余票为1时,三个线程进入来买票 * 1.A线程:看到conut>0,进入,正在出票的时候,count还没来得及做数据的变更操作 * 2.B线程:这个时候,B也进来了,因为conut还没有变更 * ..... * 这就是多线程,进入产生时间偏的问题-->>这里为了更好的模拟实际中的放票状态,就引入了一个Thread.sleep,使线程进行休眠的操作 * */ public class UnSafe { public static void main(String[] args) { Runnable r = new Ticket(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } static class Ticket implements Runnable{ private int conut = 10; @Override public void run() { while (conut > 0){ System.out.println("正在准备卖票"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } conut--; System.out.println("余票:"+conut); } } } } 8.synchronized锁
注意:看同一把锁!!!!
同步代码块和同步方法都是隐式锁 1.同步代码块package com.kkb; /** * 所谓上锁:就是在一个线程正在执行任务时,其他的对象只能在外面排队,因为这个事物现在的情况对外是不开放的 * 指定事物中的一个锁对象,在一个线程进入时,这个对象就会被标记上一把锁 * 要看同一把锁 */ public class Safe_Synchronized { public static void main(String[] args) { Runnable r = new Ticket(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } static class Ticket implements Runnable{ private int conut = 10; private Object o = new Object(); //注意这里的o为了保证这个事物中存在一个可以上锁的对象 @Override public void run() { while (true) { synchronized (o) { if (conut > 0) { System.out.println(Thread.currentThread().getName() + "正在准备卖票"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } conut--; System.out.println("余票:" + conut); }else { break; } } } } } } 2.设计为同步方法 * 注意这里面锁方法的时候,锁的对象就是这个方法饿地址上加锁,一个一个进入此方法 * 我们打印出来的this就是:com.kkb.Safe_Synchronized_To_method$Ticket@3694916f * 这个方法的地址 只需要在这个方法上加上synchronized进行标志package com.kkb; /** * 注意这里面锁方法的时候,锁的对象就是这个方法饿地址上加锁,一个一个进入此方法 * 我们打印出来的this就是:com.kkb.Safe_Synchronized_To_method$Ticket@3694916f * 这个方法的地址 */ public class Safe_Synchronized_To_method { public static void main(String[] args) { Runnable r = new Ticket(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } static class Ticket implements Runnable{ private int conut = 10; // private Object o = new Object(); //不需要这个对象了 //因为锁方法的时候锁的其实就是this,这个save方法的this //注意这里的o为了保证这个事物中存在一个可以上锁的对象 //com.kkb.Safe_Synchronized_To_method$Ticket@3694916f @Override public void run() { while (true) { boolean sale = sale(); if (!sale){//如果没票了就结束 break; } } } public synchronized boolean sale(){ if (conut > 0) { System.out.println(Thread.currentThread().getName() + "正在准备卖票"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } conut--; System.out.println("余票:" + conut); System.out.println(this); }else { return false; } return true; } } } 3.显示锁Lock l = new ReentrantLock();package com.kkb; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * */ public class Safe_Synchronized_Lock { public static void main(String[] args) { Runnable r = new Ticket(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } static class Ticket implements Runnable{ private int conut = 10; //给一把显式锁 private Lock l = new ReentrantLock();//Lock锁接口的实现类 @Override public void run() { while (true) { //每次一个线程进入就会加上一个锁,其他线程无法进入 l.lock();//加锁 boolean sale = sale(); l.unlock();//解锁 if (!sale){//如果没票了就结束 break; } } } public boolean sale(){ if (conut > 0) { System.out.println(Thread.currentThread().getName() + "正在准备卖票"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } conut--; System.out.println("余票:" + conut); }else { return false; } return true; } } } 4.公平锁和不公平锁
就是在声明显式锁的时候加上一个true.
排队一个一个进,不会出现线程争先恐后的,谁抢到就是谁的 Lock l = new ReentrantLock(true);Thread-0正在准备卖票 余票:9 Thread-1正在准备卖票 余票:8 Thread-2正在准备卖票 余票:7 Thread-0正在准备卖票 余票:6 Thread-1正在准备卖票 余票:5 Thread-2正在准备卖票 余票:4 Thread-0正在准备卖票 余票:3 Thread-1正在准备卖票 余票:2 Thread-2正在准备卖票 余票:1 Thread-0正在准备卖票 余票:0 9.多线程交互问题
线程的wait和线程的唤醒notifyAll
再引入一个变量交替执行 10.线程池
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁的船舰线程和销毁线程需要时间.线程池就是一个可以容纳多个线程的容器,池中的线程可以反复的使用,省区了频繁创建线程对象的操作,节省了大量的时间和资源.
1.创建线程
2.创建任务
3.执行任务
4.关闭线程
1.缓存线程池
2.定长线程池
3.单线程池
4.周期定长线程池
坦克世界WG自己都看不下去了?亲儿子T54数据被削弱T34M54各位车长老爷们大家好啊,这里是坦克零距离。此前我为大家做过前瞻的S系7级金币中坦T34M54在超测服中得到了一次削弱,原本该车的综合性能可以说是非常强势,也许WG自己都
三国杀环环相扣!一山更有一山高,武将克制关系游戏中总要有来有往才玩的开心,有些武将虽然很厉害,但是总会有让他受克制的武将出现才完整,要不然一家独大的后果就是这个武将被大家锁在家里了,出场率极低,所以整个武将关系是环环相扣的,
路人王女神赛S4落下帷幕石一童夺得单挑赛冠军圣诞之际,路人王女神赛S4在北京凯德mall(天宫院店)落下帷幕感谢各位女神球员和4位绅士代表队男球员的精彩表现!同时,也恭喜以下获奖的队伍和球员3v3海选赛冠军和亚军队伍分别是冠
一亿人的武侠梦,全都放心地交给九阴真经3D吧其实就游戏而言,没有足够的实力是不敢尝试武侠题材的,其一是对开放团队的要求非常苛刻,其二是很难做的具象化,每个人对江湖的定义都不同,在这里面找到平衡点更加困难,而九阴真经3D选择了
元宇宙,只是一时兴起的想法?文丨毛球科技很难在2021年谈论游戏,也很难不提及Metaverse。FortniteRoblox和Minecraft都可以声称正在构建它(以他们自己的方式),许多其他人试图参与其
7大经典动作游戏,个个都是童年的回忆杀亲爱的小伙伴们,大家好,我是你们的大T。童年的那些经典动作单机游戏,你都玩过哪些呢?那本期就来为大家盘点一下,当年最棒的七大经典动作单机游戏,这些作品,基本个个都是童年的回忆杀。1
帝国时代2毁灭战士MOD发布,体验全新的射击战役帝国时代的民间作者HELLKNIGHT61发行了一款略显特别的模组,这个名为毁灭时代(AgeofDoom)的MOD将经典FPS游戏毁灭战士同帝国时代2结合起来,原来的RTS玩法变成
重返帝国将会带给你无与伦比的沉浸感重返帝国在沉浸式体验方面做的相当出色。它能够让玩家在游戏过程中无意识地感到自己正在发展一种文明。究其原因,大概是它在尽可能多的细节上还原了真实的城市。在重返帝国游戏中,玩家可以安排
战斗更轻松玩家自制最终幻想7重制版视距MODMOD作者TohruAdachi近日为最终幻想7重制版制作了一款MOD,让玩家可以调整游戏中的视角。TohruAdachi其实是对CE参数进行了一些调整,玩家在使用之后便可以将视距
王者荣耀排位打累了?克隆大作战让你获得双倍快乐王者荣耀已经上线了好几年,时至今日依旧处于火热的状态,经过岁月的沉淀,游戏界面清爽了很多,局内场景视觉效果也是拉满。与此同时,玩家们的玩法也逐渐不一样了,从最开始凭借着排位和匹配激
原神和幻塔哪个更适合平民玩家?进幻塔第一眼就能够明白了游戏中的笔杆王者,每日靠玩游戏过日子,玩网游也有20个年头,我有自己独特的见解,作为一个10年不脱坑的老玩家,如果文章写的有什么问题,请重喷!如果大家觉得好,请转发加点赞!非常感谢