快速认识线程

秃桔子 2019-06-12 16:05:00 阅读数:16 评论数:0 收藏数:0

 本文参考自Java高并发编程详解

 

1、创建并启动一个线程

下面是不添加线程的程序代码。

package concurrent.chapter01;

import java.util.concurrent.TimeUnit;
public class TryConcurrency {
    public static void main(String[] args) {
        browseNews();
        enjoyMusic();
    }
    private static void browseNews() {
        while(true) {
            System.out.println("Uh-huh,the good news.");
            sleep();
        }
    }
    private static void enjoyMusic() {
        while(true) {
            System.out.println("Uh-huh,the nice music");
            sleep();
        }
    }
    private static void sleep(int i) {
        try {
            TimeUnit.SECONDS.sleep(i);
        }catch (Exception e) {
            
        }
    }
}

运行结果如下:

程序永远不会执行第二个方法。因此我们需要使用线程。

这里通过匿名内部类的方式创建线程,并且重写其中的run方法,使程序交互运行。

package concurrent.chapter01;

import java.util.concurrent.TimeUnit;
public class TryConcurrency {
    public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                enjoyMusic();
            }
        }.start();
        browseNews();
    }
    private static void browseNews() {
        while(true) {
            System.out.println("Uh-huh,the good news.");
            sleep();
        }
    }
    private static void enjoyMusic() {
        while(true) {
            System.out.println("Uh-huh,the nice music");
            sleep();
        }
    }
    private static void sleep(int i) {
        try {
            TimeUnit.SECONDS.sleep(i);
        }catch (Exception e) {
            
        }
    }
}

运行结果如下:

注意:

1、创建一个线程,需要重写Thread中的run方法,Override的注解是重写的标识,然后将enjoyMusic交给他执行。

2、启动新的线程需要重写Thread的start方法,才代表派生了一个新的线程,否则Thread和其他普通的Java对象并无区别,start放法是一个立即返回方法,并不会让程序陷入阻塞。

如果使用Lambda表达式改造上面的代码,那么代码会变得更简洁。

public static void main(String[] args) {
        new Thread(TryConcurrency::enjoyMusic).start();
        browseNews();
    }

2、线程的创建与结束生命周期。

1、线程的new状态。

当我们用关键字new创建一个Thread对象时,此时他并不处于执行状态,因为没用start启动该线程,那么线程的状态为NEW状态,准确的说,它只是Thread对象的状态,因为在没用start之前,该线程根本不存在,与你用new创建一个普通的Java对象没什么区别。

2、线程的RUNNABLE状态

线程对象进入RUNNABLE状态必须调用start方法,那么此时才是真正地在JVM中创建了一个线程,线程一经启动就可以立即执行吗?答案是否定的,线程的运行与否和进程一样都要听令于CPU的调度,那么我们把这个中间状态成为可执行状态,也就是说它具备执行的资格,但是并没有真正地执行起来,而是等待CPU的调度。

3、线程的RUNNING状态

一旦CPU通过轮询或者其他方式从任务可执行队列中选中了线程,那么此时它才能真正的执行自己的逻辑代码,需要说明一点是一个正在RUNNING状态的线程事实上也是RUNNABLE的,但是反过来则不成立。

在该状态中,线程的状态可以发生如下的状态转换。

  1. 直接进入TERMINATED状态,比如调用JDK已经不推荐使用的stop方法或者判断某个逻辑标识。
  2. 进入BLOCKED状态,比如调用了sleep,或者wait方法而加入了waitSet中。
  3. 进行某个阻塞的IO操作,比如因网络数据的读写而进入了BLOCKED状态。
  4. 获取某个锁资源,从而加入到该锁的阻塞队列中而进入了BLOCKED状态。
  5. 由于CPU的调度器轮询使该线程放弃执行,进入RUNNABLE状态。
  6. 线程主动调用yield方法,放弃CPU执行权,进入RUNNABLE状态。

 4、线程的BLOCKED状态

BLOCKED为线程阻塞时的状态,它能进入以下几个状态:

  1. 直接进入TERMINATED状态,比如调用JDK已经不推荐使用的stop方法或者JVMCrash
  2. 线程阻塞的操作结束,比如读取了想要的数据字节进入到RUNNABLE状态。
  3. 线程完成了指定时间的休眠,进入到了RUNNABLE状态
  4. Wait中的线程被其他线程notify/notifyall唤醒,进入RUNNABLE状态。
  5. 线程获取到了某个锁资源,进入RUNNABLE状态。
  6. 线程在阻塞过程中被打断,比如其他线程调用了interrupt方法,进入RUNNABLE状态。

 5、线程的TERMINATED状态

TERMINATED是一个线程的最终状态,在该状态中,线程将不会切换到其他任何状态,线程进入Terminated状态意味着整个线程的生命周期结束了,下列情况将会使线程进入Terminated状态。

  1. 线程运行正常结束,结束生命周期。
  2. 线程运行出错意外结束
  3. JVM崩溃,导致所有的线程都结束。

3、线程的start方法是什么?

首先:Thread start源码如下:

public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != )
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    private native void start0();

start方法的源码足够简单,其实最核心的部分是start0这个本地方法,也就是JNI方法;

也就是说在start方法中会调用start0方法,那么重写的那个run方法何时被调用了呢?

实际上在开始执行这个线程的时候,JVM将会调用该线程的run方法,换言之,run方法是被JNI方法start0调用的,仔细阅读start的源码将会总结出如下几个知识要点。

  1. Thread被构造后的NEW状态,实际上threadStatus这个内部属性为0.
  2. 不能俩次启动Thread,否则就会出现IllegalThreadStateException异常。
  3. 线程启动后会被加入到一个ThreadGroup中。
  4. 一个线程生命周期的结束也就是到了terminated再次调用start方法是不允许的,也就是说Terminated状态是没有办法回到runnable状态的。

如执行以下代码:

import java.util.concurrent.TimeUnit;

public class A {
    public static void main(String[] args) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep();
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        thread.start();
        thread.start();
    }
}

此时程序就会抛出

当我们改下代码,也就是生命周期结束后,再重新调用时。

import java.util.concurrent.TimeUnit;

public class A {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep();
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        thread.start();
        TimeUnit.SECONDS.sleep();
        thread.start();
    }
}

我们会发现程序同样会抛出illegalThread异常。

注意:程序虽然同样会抛出异常,但是这俩个异常是有本质区别的。

  1. 第一个是因为重复启动,只是第二次启动时不允许的,但是此时线程是处于运行状态的。
  2. 第二次企图重新激活也抛出了非法状态的异常,但是此时没有线程,因为该线程的生命周期已经被终结。

通过以上分析我们不难看出,线程真正的执行逻辑是在run方法中,通常我们会把run方法成为线程的执行单元。

如果我们没有重写run,那run就是个空方法。

Thread的run和start是一个比较经典的模板设计模式,父类编写算法结构代码,子类实现逻辑细节,下面是一个简单的模板设计模式。

package concurrent.chapter01;

public class TemplateMethod {
    public final void print(String message) {
        System.out.println("###");
        wrapPrint(message);
        System.out.println("###");
    }
    protected void wrapPrint(String message) {
        
    }
    public static void main(String[] args) {
        TemplateMethod t1 = new TemplateMethod() {
            @Override
            protected void wrapPrint(String message) {
                System.out.println("*"+message+"*");
            }
        };
        t1.print("Hello Thread");
        TemplateMethod t2 = new TemplateMethod() {
            @Override
            protected void wrapPrint(String message) {
                System.out.println("+"+message+"+");
            }
        };
        t2.print("Hello Thread");
    }
}

运行结果如下:

4、下面是一个模拟营业大厅叫号机的程序

假设共有4台出号机,这就意味着有4个线程在工作,下面我们用程序模拟一下叫号的过程,约定当天最多受理50笔业务,也就是说号码最多可以出到50

代码如下:

package concurrent.chapter01;

public class TicketWindow extends Thread{
    private final String name;
    private static final int MAX = ;
    private int index = ;
    public TicketWindow(String name) {
        this.name=name;
    }
    @Override
    public void run() {
        while(index<=MAX) {
            System.out.println("柜台:"+name+" 当前号码是:"+(index++));
        }
    }
    public static void main(String[] args) {
        TicketWindow t1 = new TicketWindow("一号初号机");
        t1.start();
        TicketWindow t2 = new TicketWindow("二号初号机");
        t2.start();
        TicketWindow t3 = new TicketWindow("三号初号机");
        t3.start();
        TicketWindow t4 = new TicketWindow("四号初号机");
        t4.start();
    }
}

运行结果如下:

显然这不是我们想看到的。如何改进呢?

这里我将index设置为staic变量

貌似有了改善。但是会出现线程安全问题。

所以Java提供了一个接口:Runnable专门用于解决该问题,将线程和业务逻辑的运行彻底分离开。

5、Runnable接口的引入及策略模式

Runnalbe接口非常简单,只是定义了一个无参数无返回值的run方法,具体代码如下:

public interface Runnable{
  void run();    
}

在很多书中,都会说,创建线程有俩种方式,第一种是构造一个Thread,第二种是实现Runnable接口,这种说法是错误的,最起码是不严谨的,在JDK中,代表线程的就只有Thread这个类,我们在前面分析过,线程的执行单元就是run方法,你可以通过继承Thread然后重写run方法实现自己的业务逻辑,也可以实现Runnable接口实现自己的业务逻辑,代码如下:

@override
public void run(){
   if(target!=null){
   target.run(); 
   }    
}

上面的代码段是Thread run方法的源码,我们从中可以去理解,创建线程只有一种方式,那就是构造Thread类,而实现线程的执行单元则有俩种方式,第一种是重写Thread的run方法,第二种是实现Runnable接口的run方法,并将Runnable实例用作构造Thread的参数。

策略模式

其实无论是Runnable的run方法还是,Thread本身的run方法都说想将线程的控制本身和业务逻辑的运行分离开,达到职责分明,功能单一的原则,这一点与GoF设计模式中的策略设计模式很相近。

以JDBC来举例子:

package concurrent.chapter01;

import java.sql.ResultSet;

public interface RowHandler <T>{
    T handle(ResultSet set);
}

rowhandler接口只负责对从数据库中查询出来的结果集进行操作,至于最终返回成什么样的数据结构,需要自己去实现,类似于Runnable接口。

package concurrent.chapter01;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class RecordQuery {
    private final Connection connection;
    
    public RecordQuery(Connection connection) {
        this.connection = connection;
    }
    public<T> T query(RowHandler<T> handler,String sql,Object... params) throws SQLException{
        try(PreparedStatement stmt = connection.prepareStatement(sql)){
            int index = ;
            for(Object param:params) {
                stmt.setObject(index++,param);
            }
            ResultSet resultSet = stmt.executeQuery();
            return handler.handle(resultSet);
        }
    }
}

上面的代码的好处就是可以用Query方法应对任何数据库的查询,返回结果的不同只会因为你传入RowHandler的不同而不同,同样RecodeQuery只负责数据的获取,而RowHanlder则只负责数据的加工,职责分明,每个类均功能单一。

重写Thread类的run方法和实现Runnable接口的run方法是不能共享的,也就是说A线程不能把B线程的run方法当作自己的执行单元,而使用Runnable接口则很容易就能实现这一点即使用同一个Runnable的实例构造不同的实例。

如果不明白的话,看下面的代码。

package concurrent.chapter01;

public class TicketWindowRunnable implements Runnable{
    private int index = -;
    private final static int MAX = ;
    @Override
    public void run() {
        while(index<=MAX) {
            System.out.println(Thread.currentThread()+" 的号码是:"+(index++));
            try {
                Thread.sleep();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        final TicketWindowRunnable task = new TicketWindowRunnable();
        Thread WindowThread1 = new Thread(task,"一号窗口");
        Thread WindowThread2 = new Thread(task,"二号窗口");
        Thread WindowThread3 = new Thread(task,"三号窗口");
        Thread WindowThread4 = new Thread(task,"四号窗口");
        WindowThread1.start();
        WindowThread2.start();
        WindowThread3.start();
        WindowThread4.start();
    }
}

运行结果如下:

 

 惊不惊喜?

上面并没有对index进行static进行修饰,但是和上面被static修饰的是一个效果。原因是我们每次操作的都是同一个对象即task。

 


版权声明:本文为[秃桔子]原创文章
转载请带上:http://copyfuture.com/blogs-details/201906121614543952s650ea20cn8cxj
或:https://www.cnblogs.com/godoforange/p/11008865.html


  1. 曹操攻城受阻,郭嘉无可奈何,少年却进献十计,曹操:此人不能留
  2. 业界良心!《神界:原罪2》将发布数个免费更新:首批包括大量外观
  3. HashMap 源码分析
  4. 保姆带娃的这3个坑,你踩过几个,大部分父母全中了
  5. 安徽原副省长一审被判无期!罚金一亿七千万!
  6. 越战中美空军秘密较量:56秒结束战斗
  7. 《从0开始学架构》——学习笔记(基础篇、高性能篇、高可用篇和可扩展篇)
  8. “孩子,妈妈把你背回来了……”一位特级教师母亲的泣血反思
  9. Socket通信中的多进程编程实例
  10. 降价、裁员、闭店 联合办公“一夜入冬”?
  11. VMware 虚拟机安装及部署
  12. 仅剩14场,还差97个三分!承认吧,哈登破不了库里纪录
  13. 使用OAuth保护REST API并使用简单的Angular客户端
  14. Java面试总结(集合、spring)
  15. 一线丨富途一季度营收增长37%至2.4亿港元 国际化效果凸显
  16. 有情人终成眷属 这对TVB荧幕情侣终于派糖了
  17. 修车师傅提醒:汽车这5个位置尽量少保养,保养越勤,越提前报废
  18. 单打效率最高和最低的球员:结果出人意料,印象流果然不靠谱!
  19. 命令内阁全部成员辞职之后 马杜罗又要宣布“新政“了
  20. 小米公司能力的修复、复制、升级与新建
  21. 被称为“唯一神”的幻之宝可梦炎帝,到底有多惨?
  22. 65%的程序员竟都是自学成才?
  23. 庄睿竟是聊斋中冯权的后代,结局注定眼睛被鳖精收回
  24. Python 实用爬虫-04-使用 BeautifulSoup 去水印下载 CSDN 博客图片
  25. Cobbler图文详解安装及遇到的问题说明
  26. 为什么360这种软件存活至今?程序员:打不死的小强,春风吹又生
  27. 韩雪的轮回,从京城四美到假唱女主
  28. 开源 , KoobooJson一款高性能且轻量的JSON框架
  29. 大数据技术之_05_Hadoop学习_04_MapReduce_Hadoop企业优化(重中之重)+HDFS小文件优化方法+MapReduce扩展案例+倒排索引案例(多job串联)+TopN案例+找博客共同粉丝案例+常见错误及解决方案
  30. Odoo 12 开发手册指南(八)—— 业务逻辑 – 业务流程的支持
  31. APEX国外玩家:中国玩家只会开挂!
  32. 联盟想累垮雷霆?连遭强敌赛程窒息,火箭开拓者偷着乐
  33. 怎样申请微信公众号/如何开通微信订阅号
  34. Linux RPM包验证和数字证书(数字签名)
  35. 《流浪地球》中的外骨骼动力装甲真的存在吗?
  36. 波斯为何将沿用2500年国名改为伊朗?德国人:雅利安人最优秀的
  37. 匿名函数
  38. 华为南方工厂手机生产线正常运转,部分服务器芯片可以自供
  39. 生物体的极限是多大?宇宙中会有光年大小的生物吗?
  40. 根据后台数据,渲染多个坐标在小程序中
  41. 怀孕后该吃什么?看完这篇文章就够了!
  42. 远离下肢静脉血栓,需要注意这几点!
  43. 官宣:高铁Wi-Fi将融合5G技术
  44. 宋茜穿着吊带连衣裙太耀眼了!粉色大衣才是少女风典范,被迷倒了
  45. 日本曾研制绝密武器,“死亡射线”480公里击落飞机
  46. 苹果新闻订阅有多火?传48小时有20万人订阅
  47. 网络安全 期末复习 (山东农业大学)
  48. 朴树的《平凡之路》和李宗盛的《山丘》,到底哪首歌才是人生真相?
  49. 舌尖上的食品添加剂真的很可怕吗?
  50. PyInstaller 打包 python程序成exe
  51. 全新大众途观Allspace7,车长增加215毫米,全景天窗,你会选它吗
  52. 我国有望推进船舶行业战略性重组(附股)
  53. 新研究称LAP-149是来自濒死恒星的尘埃粒 或可揭示太阳系的形成
  54. 三世恩怨说不清,文在寅势要复仇,现在黄教安来救她了
  55. 这句流传千古的话,出自一个末代小皇帝,大臣们听后纷纷泪流满面
  56. 娱记说,李沁整容上瘾?阚清子撕EX?
  57. 大贸、小贸中高档摩托车为什么不能普及的原因!
  58. 智能威胁分析之图数据构建
  59. springMvc的执行流程(源码分析)
  60. ACM菜鸡退役帖——ACM究竟给了我什么?
  61. Spring MVC源码——Root WebApplicationContext
  62. 睡觉是最好的长寿方!做到这5点,想变老都难
  63. 38岁柳岩近照曝光,网友懵了:看半天没认出
  64. H5音乐播放器源码共享
  65. 《Python编程从入门到实践》--- 学习过程笔记(3)列表
  66. 瞬间中国:看航天员刘洋解读照片背后的故事
  67. 赵宝刚盛赞郑爽演技炸裂,直言收视不好就退休,网友反应让人心酸
  68. Entity Framework 4.1 DbContext使用记之三——如何玩转实体的属性值?
  69. “权游”第八季告诉我们:一切奋斗都可能白忙活
  70. 再看《妖猫传》,每个片段都意味深长
  71. 奇迹在此发生!盘点本世纪NBA五大末节超神表演
  72. 基于C语言的磁引导园丁机器人源程序 --单片机应用
  73. Mybatis主线流程源码解析
  74. 50岁以下省级政府副手又添一人,最年轻的是他
  75. 我的战友,成了烈士
  76. 这条消息很值钱:第一批登陆科创板的浙企会是谁?
  77. 鬼泣5:卡普空还是有点底子,享受战斗的爽快,新老手都值得一玩
  78. 一夜蒸发400元!拼的多,亏得多!
  79. 商务部:对原产于美国等国进口苯酚反倾销案调查期延长6个月
  80. 早资讯:小米多款新品接连发布;华为Mate 20系列迎最佳入手时机
  81. 香港警队开通微博,现实中的阿Sir比港片的还要帅!
  82. 真格基金徐小平:我并没有低调 我只是厌倦了重复自我
  83. C#Modbus Rtu的实现
  84. 中国古代历史上的十大无敌统帅
  85. 用引力透镜效应,发现了褐矮星双星!
  86. 深入剖析Android音频之AudioTrack
  87. 新宝马330e也可挂绿牌,用插电混合动力,纯电续航60公里6秒破百
  88. 赛道见真章,蔚来站在了立体对抗全球车企的正面战场
  89. 【网警辟谣:成都七中实验学校事件中的五大谣言】
  90. ffmpeg 实现多宫格效果,视频拼接合成
  91. 今天,我想写一篇《谈失败》...
  92. 开大张飞:我能抗典韦5斧,吕布3戟,而他1个技能我就有点顶不住
  93. 关岛是如何到美国手中的?
  94. 程序员自身价值值这么多钱么?
  95. 技术年货:美团技术沙龙合辑大放送——85个演讲,70+小时视频
  96. 美服9.5更新日志:天使莫甘娜重做归来
  97. 继阿娇大婚之后她也好事将近?百亿太子爷真的已经收心?
  98. 贵阳涉黄网红楼调查追踪:近200名警力夜查娱乐场所
  99. 糖尿病治疗新希望!人类胰岛非β细胞也可产生胰岛素
  100. Red Hat解释其改变Logo的原因:减少负面印象

  1. 前端笔记之NodeJS(一)初识NodeJS&内置模块&特点(1715)
  2. Python开发:部分第三方库无法在线安装解决方法(1521)
  3. Matlab 2019a 安装包下载以及安装和激活(1451)
  4. React 与 React-Native 使用同一个 meteor 后台(1341)
  5. Delphi 开发微信公众平台 (二) 用户管理(1294)
  6. C#读取excel文件提示未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序(1148)
  7. [深度应用]·实战掌握Dlib人脸识别开发教程(1114)
  8. 币安称 4000 万美元比特币被盗(1092)
  9. 《跃迁-成为高手的技术》之联机学习(1080)
  10. 独家 | 寒武纪二代芯片发布在即,提前解密如何挑战英伟达!(1011)
  11. WebGL three.js学习笔记 纹理贴图模拟太阳系运转(992)
  12. 使用 C 语言实现一个 HTTP GET 连接(978)
  13. 【译】.NET Core 是 .NET 的未来(892)
  14. Sublime Text3 最新版3207 安装及破解(819)
  15. 微软宣布 .NET 5 计划,支持跨平台、移动开发(770)
  16. 科学家在太平洋水域发现奇特的“砷呼吸”微生物(765)
  17. 75条笑死人的知乎神回复,用60行代码就爬完了(753)
  18. 小米有品员工签军令状,自动放弃年终奖!(745)
  19. Linux学习(三):XShell连接虚拟机+开通22端口(742)
  20. 【预警通告】Weblogic反序列化远程代码执行漏洞(738)
  21. layui的table参数条件缓存问题(731)
  22. Visual Studio 2019 正式发布,重磅更新,支持live share(692)
  23. 【预警通告】Apache Tomcat远程代码执行漏洞CVE-2019-0232(675)
  24. SQL简介及MySQL的安装目录详解(650)
  25. 10亿元巨贪山西吕梁原副市长张中生二审维持死刑判决(641)
  26. 5月13日公告精读丨一字跌停后,这只300亿市值的白马股出来澄清了(618)
  27. Vue之路由(608)
  28. 2019年程序员最值得学习的思维利器——任务分解(587)
  29. css-博客样式初体验(567)
  30. 如果想转行学习WEB前端,这样学也许更加利于找工作(561)
  31. 声明与定义的区别(550)
  32. 彭博社:苹果A13芯片即将产量 新iPhone"浴霸"无疑(542)
  33. MongoDB创建数据库和删除数据库05-14学习笔记(495)
  34. PJzhang:Lucifer1993的struts-scan漏洞全量检测工具(494)
  35. K8s集群安装--最新版 Kubernetes 1.14.1(494)
  36. 吴奇隆当爹!前妻马雅舒开心复出拍戏,颜值吸睛气质超赞(491)
  37. 【威胁通告】Oracle全系产品2019年4月关键补丁更新(485)
  38. 英媒:阿里将允许外国零售商在阿里平台上销售商品(477)
  39. Confluence SSRF及远程代码执行漏洞处置手册(473)
  40. 舍命生子产妇吴梦丈夫怒斥:没抢肺源不是精神分裂,网友断章取义(473)
  41. 美方拟升级关税措施?中方:反制!(463)
  42. Visual Studio 2019 正式发布(462)
  43. 香饽饽!米兰双雄均有意荷兰小将贝尔赫韦因(460)
  44. 短视频内容重复,如何伪原创处理(457)
  45. [翻译] Visual Studio 2019: 极速编码. 智能工作. 创造未来.(439)
  46. 绿盟科技互联网安全威胁周报NSFOCUS-19-13(437)
  47. 机器学习 ML.NET 发布 1.0 RC(436)
  48. 刘强东身边的CXO还有谁“幸存”(432)
  49. 阿里巴巴2018年纳税516亿元 同比增40%(428)
  50. 告诉你去越南芽庄必带回的好东西(418)
  51. 宝宝多大可以自己吃饭?错过孩子独立吃饭黄金期,等着后悔吧(407)
  52. 针对django2.2报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6 in position 9737: ill....(391)
  53. 小米手机卖不动了?(390)
  54. 太奇葩!买100元债只给1.63元购物券和1.11元现金?网友炸锅:得买多少债券才能换一双鞋(389)
  55. 马光远:全球货币政策进入摇摆期,包括房价的资产价格何去何从(389)
  56. 我司使用了六年的分布式锁(384)
  57. 雷军清华演讲实录:小米9年的创新、变革与未来(382)
  58. 积分一样却选手下败将出战国际赛,《最强大脑》云队选手被坑了?(377)
  59. F#周报2019年第14期(372)
  60. Webpack 4教程 - 第八部分 使用prefetch和preload进行动态加载(371)
  61. Spring Boot 2.1.5 正式发布,1.5.x 即将结束使命!(370)
  62. 报告显示:一季度中国家庭总资产缩水而消费支出增加(343)
  63. 《最强大脑》要垮?桑洁魏坤琳出轨细节被扒,戚薇才是神助攻(340)
  64. 他联系叙恐怖分子“卖军火”,称能搞到2000枚导弹,关键时刻中国警察出手(339)
  65. 直认与老公感情淡了!27岁TVB上位女星:我们不是好熟(339)
  66. 谁是苏小明饭局爆粗偷拍者?知情人称另有其人(327)
  67. Oracle甲骨文大规模裁员,你背离时代就会被淘汰(327)
  68. 苹果应用商店被判垄断?然而并没有(324)
  69. 日本明仁天皇退位,日本“平成”年代结束(318)
  70. 华电教授孙玉兵被指与昔日同学共同学术造假,多所高校调查(312)
  71. 迪玛希好惨!昨晚《歌手》为声入人心男团帮帮唱,却再被指控侵权(311)
  72. linux系统安装cdcfordb2udb(309)
  73. 女友被曝插足许志安郑秀文婚姻 知情人透露马国明已下定决心分手(309)
  74. 智慧停车场系统开发建设解决方案(306)
  75. F#周报2019年第15期(299)
  76. shopify网站转化率优化之结账页checkout优化(293)
  77. 真实!这部8.5分的缉毒剧,毒贩公然贿赂警察:80万,把我放出去(285)
  78. 威廉王子出轨凯特王妃闺蜜? 外媒称婚外情致兄弟反目(285)
  79. spring-cloud-sleuth+zipkin源码探究(283)
  80. 深度学习python的配置(Windows)(282)
  81. NodeJs之邮件(email)发送(280)
  82. 许志安出轨视频系蓄谋偷拍?司机被曝收40万装红外摄像头(280)
  83. 赌命生子九个月后,吴梦离世:前半辈子任性了,我用生命买单(280)
  84. 视觉中国深夜道歉:全面配合监管部门彻底积极整改(278)
  85. 新更新kb4493472导致无法正常开机(267)
  86. 韦杰落网,金诚集团终局(265)
  87. 美国各州18年人均GDP排名(附中国各省市区人均GDP排名)(265)
  88. 她做个半永久眉毛就被说整容了?(263)
  89. 【硬盘版】下载利器IDM+优特(uTorrent)BT下载器类(263)
  90. 阿里 EasyExcel 使用及避坑(263)
  91. 机器学习基石笔记:01 The Learning Problem(258)
  92. Google AI 系统 DeepMind 高中数学考试不及格(258)
  93. 华为推出方舟编译器 称可提升安卓系统效率(256)
  94. 张丹峰出轨最新锤来了!毕滢的朋友圈简直刷新下限啊!(255)
  95. 如何设置使chrome新标签页中打开链接自动跳转到新标签页?(254)
  96. TikTok抖音海外版安卓版、ios、网页版多种下载观看姿势~(254)
  97. 山东庆云民企3000亩土地被贱卖 国企接盘拟转性(252)
  98. 不要996!程序员创建955.WLB不加班公司名单,GitHub周榜第二(251)
  99. 河南汝州农商行“百万丢款案”调查,两级法院现“判决书打架”(244)
  100. 那些年,我们一起看的毛片(244)

  1. 「解局」习近平此时出访朝鲜,有何深意?
  2. 在北京月薪多少,才能吃得起24.75元/斤的水培蔬菜?
  3. thinkphp整合系列之极验滑动验证码geetest
  4. Java线程之Synchronized用法
  5. 不定个数的输入数字 并做复数运算
  6. 突发!四川宜宾长宁县发生6.0级地震,记者连夜奔赴现场
  7. 长春长生疫苗案新动向!91亿元罚没款将被强制执行
  8. 重写类加载器,实现简单的热替换
  9. Java核心技术梳理-IO
  10. java基础知识入门
  11. spark 机器学习 随机森林 原理(一)
  12. React总述
  13. # 大项目之网上书城(四)——主页(下中)
  14. TypeScript `this` 入参
  15. 绿盟科技互联网安全威胁周报NSFOCUS-2019-24
  16. 正式测定!四川宜宾发生6级地震
  17. 项目测试操作规范
  18. es6入门7--Set Map数据结构
  19. 这个要起诉华为的人啥来头?刚刚说死磕是因为任正非,网友这样说
  20. robotframework - 框架做接口自动化get请求
  21. 吉林珲春1.3级地震原因公布:碎石场两次爆破作业所致,共用6吨炸药
  22. PHP面向对象(二)
  23. SpringBoot整合Swagger和Actuator
  24. Jira集成方式:Cookie方式登录
  25. 高仿富途牛牛-组件化(二)-磁力吸附
  26. 校园表白墙APP使用体验
  27. SpringBoot整合Swagger和Actuator
  28. [hdu517] 小奇的集合
  29. 论编程与武学的相关性
  30. Python 元组
  31. Hibernate事务管理
  32. 京东618发布1-17日战报:低线市场突破 大牌名牌受青睐
  33. springboot如何读取自定义配置项
  34. 报文、报文段、分组、包、数据报、帧、数据流
  35. Qt信号阻塞和断开信号槽
  36. mysql 第三天 实体与实体的关系
  37. mysql 第三天 高级查询
  38. mysql 第三天 group by子句
  39. mysql 第三天 having子句
  40. Python————面向对象高级特性
  41. Java之异常丢失
  42. 2091操作系统引论
  43. 【nodejs原理&源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick
  44. 美方指责我军在吉布提“限制国际空域”,外交部:与事实完全不符
  45. 张曼玉再谈梁朝伟,真羡慕她任性妄为的这一生
  46. 在return中使用finally
  47. 深水炸弹!投保香港保险一夜归零,数百投资人、数亿投资打水漂,还倒欠管理费!香港保险神话被打破?
  48. Nginx location匹配规则
  49. 电商、P2P等大型互联网系统包含哪些业务模块?
  50. 【Java源码】集合类-优先队列PriorityQueue
  51. 一篇文章说完Java的垃圾回收过程
  52. Python基础数据类型(五) dict字典
  53. 微信商城小程序 带java后台源码
  54. 封装
  55. SpringBoot + Redis:基本配置及使用
  56. 菜鸟初学 node 推荐 亲测easy
  57. 科学家证实在地球深处的确隐藏着未知磁力源!
  58. 人类虐待机器人遭反杀,网友:心疼机器人
  59. 以色列公司Cellebrite宣称可解锁所有iOS 12设备
  60. 世界第一大岛格陵兰岛出问题:单日融冰量达20亿吨
  61. 龙芯胡伟武:补课18年 未来几年将同国际主流产品竞争
  62. 新能源界首陷“漏电门”奥迪将召回1644辆电动车e-tron
  63. 许家印大笔押注新能源:恒大集团1200亿沈阳投资建厂造车
  64. 亦真亦幻 AI让虚拟世界“触手可感”
  65. 大学社团“拉赞助”成为个人隐私泄露的重灾区
  66. 地量地价,将迎变盘?看看大V怎么说(6月17日)
  67. 富士康科技集团发声明否认“撤离大陆”
  68. 5G来了,需要更换SIM卡吗?
  69. 任正非:遭受打压不会阻止华为前进的步伐
  70. MIT新机器人“成精了” 能通过视觉和触觉识别事物
  71. 让港股小股东买得起?阿里计划分拆普通股:1拆8
  72. 任正非:未来华为业务不会拆分也不会卖掉
  73. 英伟达与ARM打造超级计算机 开发气候预测与核武器建模系统
  74. 任正非:华为不会像高通一样 收那么高的专利费
  75. 渐冻人有望“解冻”
  76. 富士康科技集团声明否认“撤离大陆”:无撤资现象发生
  77. 人体就像马赛克,大量组织充满致癌突变
  78. 超级计算机500强史上首次全部千万亿次!中国神威太湖之光第三
  79. 哈勃太空望远镜观测到有“大心脏”的小星系
  80. 节能超算Green500排行榜公布 NVIDIA笑到了最后
  81. 兴衰成败三百年:俄罗斯数学的光荣与梦想
  82. 任正非:通过科学的数学模型 AI可继承人类智慧
  83. 美国航空机上 WiFi 全面升级为卫星网络,空中上网的体验更好了
  84. 4G的小程序与5G的Chromium OS?
  85. 2249万元!UCloud 中标中移信息技术“异地多活”云平台试点工程
  86. 地球历史的24个转折点
  87. 激光摧毁血液中的癌细胞
  88. 什么是报文
  89. Item
  90. Eclipse 常用快捷键及使用技巧
  91. 2.urllib库的使用
  92. java基础
  93. 【Swift】WKWebView与JS的交互使用
  94. python基础数据类型和初级应用
  95. Echarts 设置 图标 默认平铺 数据为零时绘画
  96. uni-app学习(三)好用的插件1
  97. java 学习第一步---安装JDK以及配置环境变量
  98. Spring Boot:实现MyBatis动态创建表
  99. Django表单
  100. 《七哥说道》【第十四章:趁着夏天还在,回校园】