【Java多线程】轻松搞定Java多线程(一)
生活随笔
收集整理的這篇文章主要介紹了
【Java多线程】轻松搞定Java多线程(一)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
輕松搞定Java多線程(一)
- Java多線程詳解(一)
- 1、 線程簡介
- 2、線程的創建
- 2.1 三種創建方式
- 2.2 Thread
- 2.3 實現Runnable
- 2.3.1 初識并發問題
- 2.3.2 案例:龜兔賽跑
- 2.4 實現Callable接口
- 3、靜態代理模式
- 4、Lambda表達式
- 4.1 推導lambda表達式
- 4.2 簡化lambda表達式
Java多線程詳解(一)
1、 線程簡介
注意:很多多線程是模擬出來的,真正的多線程是指有多個cpu,即多核。如果是模擬出來的多線程,即在一個cpu的情況下,在同一個時間點,cpu只能執行一個代碼,因為切換的很快。所以有同時執行的錯覺。
- 線程就是獨立的執行路徑;
- 在程序運行時,即使沒有自己創建線程,后臺也會有多個線程,如主線程,gc線程;
- main()稱之為主線程,為系統的入口,用于執行整個程序;
- 在一個進程中,如果開辟了多個線程,線程的運行由調度器安排調度,調度器是與操作系統緊密相關的,先后順序是不能人為干預的;
- 對同一份資源操作時,會存在資源搶奪的問題,需要加入并發控制;
- 線程會帶來額外的開銷,如cpu調度時間,并發控制開銷;
- 每個線程在自己的工作內存交互,內存控制不當會造成數據不一致。
2、線程的創建
2.1 三種創建方式
2.2 Thread
- 自定義線程類繼承Thread類
- 重寫run()方法,編寫線程執行體
- 創建線程對象,調用start()方法啟動線程
執行結果:
2.3 實現Runnable
- 定義MyRunnable類實現Runable接口
- 實現run()方法,編寫程序執行體
- 創建線程對象,調用start()方法啟動線程
小結:
- 繼承Thread類
- 子類繼承Thread類具備多線程能力
- 啟動線程:子類對象.start();
- 不建議使用:避免OOP單繼承局限性
- 實現Runnable接口
- 實現接口Runnable具有多線程的能力
- 啟動線程:傳入目標對象+Thread對象.start();
- 推薦使用:避免單繼承局限性,靈活方便,方便同一個對象被多個線程使用
2.3.1 初識并發問題
/*** 多個線程同時操作一個對象* 買火車票的例子*//*** 發現問題:* 多個線程操作同一個資源的情況下,線程不安全,數據紊亂*/ public class TestThread4 implements Runnable {/*** 票數*/private int ticketsNums = 20;@Overridepublic void run() {while (true) {if (ticketsNums <= 0) {break;}/*** 模擬延時*/try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "拿到了" + ticketsNums-- + "票");}}public static void main(String[] args) {TestThread4 ticket = new TestThread4();new Thread(ticket, "小明").start();new Thread(ticket, "老師").start();new Thread(ticket, "黃牛").start();} }2.3.2 案例:龜兔賽跑
/*** 模擬龜兔賽跑*/ public class Race implements Runnable {/*** 勝利者*/private static String winner;@Overridepublic void run() {for (int i = 0; i <= 100; i++) {/*** 模擬兔子睡覺*/if (Thread.currentThread().getName().equals("兔子") && i%10 == 0) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}/*** 判斷比賽是否結束*/boolean flag = gameOver(i);/*** 如果比賽結束,退出程序*/if (flag) {break;}System.out.println(Thread.currentThread().getName() + "跑了" + i + "步");}}/*** 判斷是否完成比賽*/private boolean gameOver(int steps) {/*** 判斷是否有勝利者*/if (winner != null) {return true;} else if (steps >= 100){winner = Thread.currentThread().getName();System.out.println("winner is " + winner);return true;}return false;}public static void main(String[] args) {Race race = new Race();new Thread(race, "兔子").start();new Thread(race, "烏龜").start();} }2.4 實現Callable接口
Callable的好處:
3、靜態代理模式
靜態代理模式總結:
真實對象和代理對象都要實現同一個接口
代理對象代理真實角色
好處:
代理對象可以做很多真實對象做不了的事情
真實對象專注做自己的事情
/*** Jack結婚的例子,婚慶公司幫助Jack結婚*/ public class StaticProxy {public static void main(String[] args) {WeddingCompany weddingCompany = new WeddingCompany(new Jack());weddingCompany.HappyMarry();}}interface Marry {void HappyMarry(); }/*** 真實角色*/ class Jack implements Marry {@Overridepublic void HappyMarry() {System.out.println("Jack要結婚了");} }/*** 代理角色*/ class WeddingCompany implements Marry {private Marry target;public WeddingCompany(Marry target) {this.target = target;}@Overridepublic void HappyMarry() {before();this.target.HappyMarry();after();}private void before() {System.out.println("結婚之前,布置現場");}private void after() {System.out.println("結婚之后,收拾東西");} }4、Lambda表達式
- 其實質屬于函數式編程的概念
- 為什么要使用lambda表達式
- 避免匿名內部類定義過多
- 可以讓你的代碼看起了很簡潔
- 去掉了一堆沒有意義的代碼,只留下核心的邏輯
-
函數式接口的定義:
- 任何接口,如果只包含唯一一個抽象方法,那么它就是一個函數式接口。
- 對于函數式接口,我們可以通過lambda表達式來創建該接口的對象。
4.1 推導lambda表達式
/*** 推導lambda表達式*/ public class TestLambda1 {/*** 3.靜態內部類*/static class Like2 implements ILike {@Overridepublic void lambda() {System.out.println("I Like Lambda2");}}public static void main(String[] args) {ILike like = new Like();like.lambda();like = new Like2();like.lambda();/*** 4.局部內部類*/class Like3 implements ILike {@Overridepublic void lambda() {System.out.println("I Like Lambda3");}}like = new Like3();like.lambda();/*** 5.匿名內部類,沒有類的名稱,必須借助接口或者父類*/like = new ILike() {@Overridepublic void lambda() {System.out.println("I Like Lambda4");}};like.lambda();/*** 6.用lambda簡化*/like = () -> {System.out.println("I Like Lambda5");};like.lambda();}/*** 1.定義一個函數式接口*/interface ILike {void lambda();}/*** 2.實現類*/static class Like implements ILike {@Overridepublic void lambda() {System.out.println("I Like Lambda");}} }4.2 簡化lambda表達式
public class TestLambda2 {public static void main(String[] args) {ILove love = new Love();love.love(1);love = (int a) -> {System.out.println("I Love Lambda-->" + a);};love.love(2);/*** 簡化1:參數類型*/love = (a) -> {System.out.println("I Love Lambda-->" + a);};love.love(3);/*** 簡化2:簡化括號*/love = a -> {System.out.println("I Love Lambda-->" + a);};love.love(4);/*** 簡化3:簡化花括號*/love = a -> System.out.println("I Love Lambda-->" + a);love.love(5);} }interface ILove {void love(int a); }class Love implements ILove {@Overridepublic void love(int a) {System.out.println("I Love Lambda-->" + a);} }總結:
總結
以上是生活随笔為你收集整理的【Java多线程】轻松搞定Java多线程(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于STM32的智能循迹避障小车
- 下一篇: Rails的启动