多线程

  • java

java中对于大量的比较耗时的任务多采用多线程对方式对任务进行处理,同时由于进程和线程

本身是通过宿主机OS进行管理的,当在cpu核数较少或线程分配不当 会导致多线程的效果不佳的事常有发生

代码片段:

    //处理器核心数
int processor = Runtime.getRuntime().availableProcessors();
//XSSFWorkbook 一次只能写入六万多条数据,所以这里最好使用SXSSFWorkbook
SXSSFWorkbook workBook = new SXSSFWorkbook();
//创建格式
CellStyle style = workBook.createCellStyle();
//居中格式
style.setAlignment(HorizontalAlignment.CENTER);
//手工创建线程池
ExecutorService executorService = new ThreadPoolExecutor(processor, processor, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque(),
new ThreadFactoryBuilder().setNameFormat("poi-task-%d").build());
//计数器 等待线程池中的线程执行完毕
CountDownLatch countDownLatch = new CountDownLatch(processor);
for (int i = 0; i < processor; i++) {
int sheetId = i;
//放入线程池中
executorService.execute(() -> createSheet(workBook, style,sheetId, countDownLatch));
}
try {
//等待所有线程执行完毕
countDownLatch.await();
executorService.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
}
  • go

    由于进程和线程都是基于OS管理的,不可避免的产生开销;go区别与以上两者使用的是协程(goroutine),协程是线程的内的细颗粒化,

    同时它是被go自己管理的所以开销相当的小,同时一个go应用可以轻松构建上百万个goroutine,不仅如此,go也提供了通道(channel)方便

    对协程之间进行数据交互

代码片段:

import (
"fmt"
"sync"
) func says(s string, gw *sync.WaitGroup) {
for i := 0; i < 5; i++ {
fmt.Println(">>> ", s)
}
gw.Done()
}
func main() {
var gw sync.WaitGroup
gw.Add(1)
go says("Hello s", &gw)
gw.Wait()
}

函数参数传递

  • java

java对于函数值对传递采取对是值传递的方式,对于基本数据类型:传递前后值所在栈的位置是不一致的(也就是被拷贝了一份)

对于非基本数据类型:虽然也会做拷贝,但实际上这前后的对象引用的是同一内存位置的值,这就造成了"引用传递的假象"

代码片段:

public class TransParams {

    public static void main(String[] args){
Person p = new Person();
p.setAge(99);
p.setName("Lisa"); System.out.println(p.getAge());
System.out.println(p);
System.out.println("======>split<====="); TransParams tp = new TransParams();
tp.setValue(p);
System.out.println(p.getAge());
System.out.println(p);
} public void setValue(Person p){
p.setAge(19);
}
}
class Person {
private Integer age;
private String name; public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

运行结果:

   99
com.task.charset.Person@7e0b37bc
======>split<=====
19
com.task.charset.Person@7e0b37bc
  • go

    go语言的处理方式不同于java,具体分两个种:拷贝传递 和 指针传递

    对于拷贝传递:不论是基本数据类型还是结构体类型,前后的值都不会是同一个

    对于引用传递:传递前后都是同一个值对象,不会存在java的理解歧义

    代码片段:

import "fmt"

func main() {
var s1 []string
fmt.Println("拷贝传递前>", s1)
tr01(s1)
fmt.Println("拷贝传递后>", s1) fmt.Println("=====><=====") var s2 []string
fmt.Println("指针传递前>", s2)
tr02(&s2)
fmt.Println("指针传递后>", s2)
} func tr01(m []string) {
m = append(m, "youth01")
} func tr02(mm *[]string) {
*mm = append(*mm, "youth02")
}

输出结果:

拷贝传递前> []
拷贝传递后> []
=====><=====
指针传递前> []
指针传递后> [youth02]

日期格式处理

  • java

在java8之前jdk仅提供了Date类型的格式化,对应的日期处理类是SimpleDateFormat,

在java8至java8之后Oracle提供了LocalDate与LocalDateTime的两种日期格式,对应的日期处理类是DateTimeFormat

代码片段:

public class Format2LocalDate {
private static final Logger LOG = LoggerFactory.getLogger(Format2LocalDate.class); private static final DateTimeFormatter DATE_FORMAT_SHORT = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss"); @Test
public void transDate(){
this.parse();
this.format();
LOG.info(".....................");
this.parseD();
this.formatD();
}
public void parse(){
String str = "20190116 12:12:22";
Date today = Date.from(LocalDateTime.parse(str,DATE_FORMAT_SHORT).atZone(DateUtil.CHINA_ZONE_ID).toInstant());
LOG.info("转换结果为> {}",today);
} public void format(){
LocalDateTime ldt = LocalDateTime.now();
LOG.info("格式化字符串> {}",ldt.format(DATE_FORMAT_SHORT)); } public final static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; public void parseD(){
String dateStr = "2019-01-01 12:22:33";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);
Date date = null;
try {
date = simpleDateFormat.parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
LOG.info("转换结果为> {}",date);
} public void formatD(){
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT); LOG.info("格式化结果为> {}",simpleDateFormat.format(date)); }
}

输出结果为:

转换结果为> Wed Jan 16 12:12:22 CST 2019
格式化字符串> 20190313 21:20:23
.....................
转换结果为> Tue Jan 01 12:22:33 CST 2019
格式化结果为> 2019-03-13 21:20:23
  • go

    go的日期处理相对于java来说十分的怪异,官方给出的例子是个固定的日期字符串,并非"yyyymmdd"这种形式,这里就不用说了

    看代码

    代码片段:

/**
官方定义的不可更改
*/
const DATE_FORMAT string = "2006-01-02 15:04:05" func main() {
parse()
format()
} func parse() {
tm := time.Now()
strs := tm.Format(DATE_FORMAT)
fmt.Println("日期转换为字符串> ", strs)
}
func format() {
tm, _ := time.Parse(DATE_FORMAT, "2019-01-01 12:12:12")
fmt.Println("字符串转换为日期> ", tm)
}

运行结果:

日期转换为字符串>  2019-03-13 21:29:30
字符串转换为日期> 2019-01-01 12:12:12 +0000 UTC

数学运算

  • java

    java的数学基本运算往往会有精度丢失问题,所以对于敏感运算建议使用BigDecimal

    代码片段:

//加减乘除都出现了对应的精度问题
public class MathCalcul {
private static final Logger LOG = LoggerFactory.getLogger(MathCalcul.class); @Test
public void calcul(){
LOG.info("加: {}",0.1 + 0.2);
LOG.info("减: {}",1.1 - 0.11);
LOG.info("乘: {}",1.13 * 100);
LOG.info("除: {}",100.13 / 100);
}
}

输出结果:

加: 0.30000000000000004
减: 0.9900000000000001
乘: 112.99999999999999
除: 1.0012999999999999
  • go

    go 不存在精度丢失问题,可以看代码可知

func main() {
fmt.Println("加: ", 0.1+0.2)
fmt.Println("减: ", 1.1-0.11)
fmt.Println("乘: ", 1.13*100)
fmt.Println("除: ", 100.13/100)
}

输出结果:

加:  0.3
减: 0.99
乘: 113
除: 1.0013

http Server

  • java

    java的http Server是基于Servlet,应对高并发时的策略是多线程,处理效率一般

    代码示例:

class MyServlet extends HttpServlet{
private static final ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings"); protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
} } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
} }
}
  • go

    go 源码是自带http包的,所以无需第三方封装,开发较为简单;应对高并发时的策略是多协程,处理效果较好

    代码示例:

import (
"fmt"
"net/http"
) func index_handle(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Whoa,Go is cool!")
}
func main() {
http.HandleFunc("/", index_handle)
http.ListenAndServe(":8000", nil)
}

常量与静态变量

  • java

    java 中常量(final) 与 静态(static) 是分开的,常量:只能动态赋值一次后不可改变 静态:类型不变

    示例:

//静态
public static String str = "hello";
//常量
public final String str2 = "hello2";
//不可变量(初始化后不可重新赋值)
public static final String str3 = "hello3";
  • go

    go 没有静态一说,只有常量(const)一说,在初始化后不能改变,其实就相当于 java中的 final + static

    示例:

const str string = "hello"

本章就到这里吧,敬请期待下一讲。(_)

现在是 2019-03-13 22:29:50,各位晚安~

20190312_浅谈go&java差异(一)的更多相关文章

  1. 20190312_浅谈go&java差异(二)

    转载请注明出处:https://www.cnblogs.com/funnyzpc/p/10801474.html 第二节内容概览 循环(for.switch) 多值返回 defer & fin ...

  2. 20190608_浅谈go&java差异(三)

    20190608_浅谈go&java差异(三) 转载请注明出处https://www.cnblogs.com/funnyzpc/p/10990703.html 第三节内容概览 多线程通讯(线程 ...

  3. 浅谈:java泛型与dao重用

    在进入今天的主题之前,我们先理解一下什么是泛型: 泛型是java中一种类型,泛型是被参数化的类型. 类型-->class 参数化-->class类型可以是任意参数 泛型存在的意义:泛型可以 ...

  4. 浅谈用java解析xml文档(四)

    继续接上一文,这一阵子因为公司项目加紧,导致最后一个解析xml文档的方式,还没有总结,下面总结使用dom4J解析xml. DOM4J(Document Object Model for Java) 使 ...

  5. 浅谈用java解析xml文档(三)

    接上一篇,本文介绍使用JDOM解析xml文档, 首先我们还是应该知道JDOM从何而来,是Breet Mclaughlin和Jason Hunter两大Java高手的创作成果,2000年初, JDOM作 ...

  6. 浅谈用java解析xml文档(一)

    关于xml本身的语法及使用的环境不多说了,网上有很多规则, 然对xml文档进行解析,一般分为四种解析方式,基于java官方文档的Dom 和Sax解析,还有就是基于 第三方jar包的 Jdom 和 Do ...

  7. 浅谈对java中锁的理解

    在并发编程中,经常遇到多个线程访问同一个 共享资源 ,这时候作为开发者必须考虑如何维护数据一致性,在java中synchronized关键字被常用于维护数据一致性.synchronized机制是给共享 ...

  8. 浅谈对java中传参问题的理解

    之前用的c/c++比较多,在c/c++中对于传参类型,无外乎就是传值.传引用.传指针这几种.但在java中,由于没有指针类型,其传参的方式也发生了相应的变化.在网上找了找,按我之前的理解,java中传 ...

  9. 浅谈一下Java String

    相信很多同学使用Java String, Java中的String方法,但是对其中的原理可能有些模糊,那么咱们就针对这块内容进行展开,让更多的同学理解和知道. public final class S ...

随机推荐

  1. JS通用模块模式 UMD

    历史 JS诞生之初面向简单页面开发, 没有模块的概念. 后来页面逐渐复杂, 人类构造到 IIFE 立即执行函数来模拟 模块: 之前也有雅虎的实践,使用命名空间 作为模块名. 最后衍生出 面向各种使用场 ...

  2. FCN网络

    https://www.cnblogs.com/gujianhan/p/6030639.html

  3. 关于Java的volatile

    volatile的作用 1.防止指令重排序 首先要理解什么是指令重排序?指令重排序的利弊?后续举例说明 2.多线程访问共享资源时,缓解synchronized重量级锁带来的性能问题 但是volatil ...

  4. Javamail pop3连接QQ邮箱遇到最深的坑

    在使用pop3邮箱连接QQ邮箱接受邮件的时候遇到如下错误 Login fail. A secure connection is requiered(such as ssl) 此时按照错误提示添加如下配 ...

  5. VGA、DVI、HDMI三种视频信号接口

    目前,电脑显示器常见的接口主要有HDMI.DP.DVI.VGA等4种接口.显示器数据线性能排名:DP>HDMI>DVI>VGA.其中 
VGA是模拟信号,已经被主流所淘汰,DVI.H ...

  6. 【easy】278. First Bad Version

    有一系列产品,从某个开始其后都不合格,给定一个判断是否合格的函数,找出N个产品中第一个不合格的产品. 正确答案: // Forward declaration of isBadVersion API. ...

  7. eclipse:插件安装总结

    1.SVN插件 首先安装SVNKIT,下载地址:https://svnkit.com/download.php 再安装Subclipse,这个在marketplace安装即可. 2.安装时报错:Una ...

  8. 创建Git 仓库及 克隆、拉取、和推送操作

    打开网址:     https://github.com/ 登录上自己创建的 Git账号   一. 创建Git 仓库          start  a project--->     输入仓库 ...

  9. python-基于tcp协议的套接字(加强版)及粘包问题

    一.基于tcp协议的套接字(通信循环+链接循环) 服务端应该遵循: 1.绑定一个固定的ip和port 2.一直对外提供服务,稳定运行 3.能够支持并发 基础版套接字: from socket impo ...

  10. Mybatis面试集合(转)

    Mybatis技术内幕系列博客,从原理和源码角度,介绍了其内部实现细节,无论是写的好与不好,我确实是用心写了,由于并不是介绍如何使用Mybatis的文章,所以,一些参数使用细节略掉了,我们的目标是介绍 ...