java中對於大量的比較耗時的任務多采用多線程對方式對任務進行處理,同時因爲進程和線程
自己是經過宿主機OS進行管理的,當在cpu核數較少或線程分配不當 會致使多線程的效果不佳的事常有發生java
代碼片斷:多線程
//處理器核心數 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)方便
對協程之間進行數據交互app
代碼片斷:函數
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對於函數值對傳遞採起對是值傳遞的方式,對於基本數據類型:傳遞先後值所在棧的位置是不一致的(也就是被拷貝了一份)
對於非基本數據類型:雖然也會作拷貝,但實際上這先後的對象引用的是同一內存位置的值,這就形成了"引用傳遞的假象"高併發
代碼片斷:post
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; } }
運行結果:ui
99 com.task.charset.Person@7e0b37bc ======>split<===== 19 com.task.charset.Person@7e0b37bc
gothis
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]
在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
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,各位晚安~