如何写代码来解决生产者消费者问题?

这个题目考验的实际上是线程间的通信和同步问题。我们再有一篇文章中,使用Object的wait和notify实现了线程间的同步。参见 : https://huster.top/htmls/615.html

继续阅读“如何写代码来解决生产者消费者问题?”

Java多线程总结(上部分)面试题解答

    自去年列下计划到现在一年有余,看了好几本书,以为已经过了很长时间,现在回头发现仅仅才过了一年而已,已经积累了不少知识,看来有目的的去学习还是有一些成效的。正好今天看到一个关于多线程的面试题,所以来总结过去所学,也是对过去知识的一个考验。

继续阅读“Java多线程总结(上部分)面试题解答”

细说Java的内存模型

    多线程之所以复杂,是因为在多线程环境下,稍有不慎就会导致诡异的问题。这个诡异表现在,他不是一定会出现,他不知道会在什么时候会以什么样的姿态出现在我们的生产环境中。为了避免犯错误,所以我们在所有可能出问题的地方都加上synchronize,那当然也是欠妥的,所以我们要搞清楚其中的细节,对我们写程序就有比较大的帮助了。

继续阅读“细说Java的内存模型”

Mybatis获取最近插入的主键

通常情况下,我们插入一条记录的mapper如下:


    @Insert("insert into experiment_info (gmt_create, gmt_modified, user_id, name, type) values (now(),now(),#{userId},#{name},#{type})")
    int saveExperimentInfo(ExperimentInfoDO infoDO);

 

但是有时候,我们需要拿到这次插入之后生成的主键应该怎么办呢? 其实很简单,只需要一句话就可以完成, 将以上的代码改为如下:

 

    @Insert("insert into experiment_info (gmt_create, gmt_modified, user_id, name, type) values (now(),now(),#{userId},#{name},#{type})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int saveExperimentInfo(ExperimentInfoDO infoDO);

 

 

其中id是默认值,可以省略不写。

还有一种办法是,生成一个主键主动传入。

使用Java原生HttpURLConnection快速的完成一个http请求

通常情况下,我们都使用Apache的HttpClient来发起一个http请求,我们再提供一个思路, 使用Java原生的HttpURLConnection发起一个http请求,示例代码如下:
继续阅读“使用Java原生HttpURLConnection快速的完成一个http请求”

另一种使用Log4j的方式

一般情况下,我们不需要关注log4j的使用,只需要写配置文件就可以实现定制。例如在spring boot的工程中,我们只需要在resource中通过logback.xml文件来配置就可以使用日志系统,但是很多时候,我们需要自我定制日志的配置。例如,我们的程序是一个二方包提供给别人使用的时候,我们该怎么定制我们的二方包的日志呢? 本文要解决的就是这个问题

继续阅读“另一种使用Log4j的方式”

Java的Serializable接口

在写RPC调用的时候,难免会用到Serializable序列化,这个时候传输的对象就必须实现java.io.Serializable接口,这个接口里面没有方法也没有属性,只有一个长长的注释,我们看下这个注释都写了啥内容,总结如下

  1. 类要能被序列化必须实现Serializable的接口,没有实现这个接口的不能被序列化和反序列化,虽然这个接口既没有方法也没有属性,仅仅是语义上的一个声明.可能抛出NotSerializableException
  2. 如果父类实现了这个接口,那么他所有的子类都可以被序列化
  3. 如果子类实现了这个接口,而父类没有,那么为了让这个子类能被序列化,父类必须有一个子类能够访问到的无参构造函数.这样做的原因是为了让子类在反序列化构建的时候能正确的初始化他的父类。
  4. 如果想要自定义序列化和反序列化的过程,那么可以实现下面几个方法。
    writeObject 用来写入序列化数据
    readObject 用来恢复序列化数据
    readObjectNoData 用来读取特殊情况,比如发送方和接收方的类信息版本不一致或者一个继承了父类一个没有继承。或者stream信息不完整或者遭到破坏.
  5.  static 和 transient 修饰的字段会被忽略
  6.  serialVersionUID建议自定义,如果不自定义会使用默认的计算规则,而计算依赖于Java的编译实现,可能会导致发送方和接收方的不一致。不一致会抛出linkInvalidClassException异常。并且建议定义成private的
    private static final long serialVersionUID = 42L;
  7. 数组类没有serialVersionUID.

继续阅读“Java的Serializable接口”

用几个简单例子理解Java的泛型并用好他

前几天和小伙伴在食堂吃饭时,正好说到了泛型,再把泛型的几个要素总结下,下面用几个简单的例子说明下,如何用好泛型。

泛型的定义

这个大家应该都不陌生,泛型是在Java1.5之后引入的,字面定义是: 声明中,具有一个或者多个类型参数的类或者接口,就是泛型类或者接口。构成格式是,类或者接口,接着用<>尖括号把对应于泛型形式类型参数的实际类型参数列表括起来。例如List\就是泛型,List就是原生态类型,而每一个泛型都对应着这么一个原生态类型。

继续阅读“用几个简单例子理解Java的泛型并用好他”

Spring boot访问js、css、图片(img)访问404无法访问的问题

问题: 今天在使用spring boot的时候,我按照spring boot的要求将css、js、图片放在规定的/src/main/resource/public/js下面,却怎么也访问不到,报的是404错误,在查找资料无果后,经过反复的实验,终于找到了问题的解决方法.

继续阅读“Spring boot访问js、css、图片(img)访问404无法访问的问题”