日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多线程与高并发(一):单机高并发应该掌握的线程基础:线程状态,异常与锁等

發布時間:2024/2/28 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程与高并发(一):单机高并发应该掌握的线程基础:线程状态,异常与锁等 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

多線程復習

多線程的基本概念


什么是一個線程?如何開啟一個線程?

package com.mashibing.juc.c_000;import java.util.concurrent.TimeUnit;public class T01_WhatIsThread {private static class T1 extends Thread {@Overridepublic void run() {for(int i=0; i<10; i++) {try {TimeUnit.MICROSECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("T1");}}}public static void main(String[] args) {//new T1().run();//這是普通的函數調用new T1().start();//這是開啟一個線程for(int i=0; i<10; i++) {try {TimeUnit.MICROSECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("main");}} }

面試題:請你告訴我啟動線程的三種方式

  • 繼承Thread,重寫run方法
  • 實現Runnable接口,重寫run方法(或Lambda表達式)
  • 通過線程池來啟動(實際上也是以上兩種之一)
package com.mashibing.juc.c_000;public class T02_HowToCreateThread {static class MyThread extends Thread {@Overridepublic void run() {System.out.println("Hello MyThread!");}}static class MyRun implements Runnable {@Overridepublic void run() {System.out.println("Hello MyRun!");}}public static void main(String[] args) {new MyThread().start(); // 第一種new Thread(new MyRun()).start(); // 第二種(1)new Thread(()->{ // 第二種(2)System.out.println("Hello Lambda!");}).start();} } //請你告訴我啟動線程的三種方式 1:Thread 2: Runnable 3:Executors.newCachedThrad

Sleep Yield Join 的含義

  • sleep:睡眠,當前線程暫停一段時間,讓給別的線程去執行。睡眠時間到,自動復活
  • yield:當前線程正在執行的時候,停下來進入等待隊列,回到等待隊列里。系統調度算法去決定哪個線程繼續運行(有可能還是自己)
  • join:在自己當前線程加入你調用的join線程,本線程等待等調用的線程運行完了,自己再去執行。(自己join自己沒有意義)
package com.mashibing.juc.c_000;public class T03_Sleep_Yield_Join {public static void main(String[] args) { // testSleep(); // testYield();testJoin();}static void testSleep() {new Thread(()->{for(int i=0; i<100; i++) {System.out.println("A" + i);try {Thread.sleep(500);//TimeUnit.Milliseconds.sleep(500)} catch (InterruptedException e) {e.printStackTrace();}}}).start();}static void testYield() {new Thread(()->{for(int i=0; i<100; i++) {System.out.println("A" + i);if(i%10 == 0) Thread.yield();}}).start();new Thread(()->{for(int i=0; i<100; i++) {System.out.println("------------B" + i);if(i%10 == 0) Thread.yield();}}).start();}static void testJoin() {Thread t1 = new Thread(()->{for(int i=0; i<100; i++) {System.out.println("A" + i);try {Thread.sleep(500);//TimeUnit.Milliseconds.sleep(500)} catch (InterruptedException e) {e.printStackTrace();}}});Thread t2 = new Thread(()->{try {t1.join();} catch (InterruptedException e) {e.printStackTrace();}for(int i=0; i<100; i++) {System.out.println("A" + i);try {Thread.sleep(500);//TimeUnit.Milliseconds.sleep(500)} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();t2.start();} }

線程狀態


如何關閉線程?
不要使用stop()關閉線程,要讓線程自己去結束。

package com.mashibing.juc.c_000;public class T04_ThreadState {static class MyThread extends Thread {@Overridepublic void run() {System.out.println(this.getState());for(int i=0; i<10; i++) {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(i);}}}public static void main(String[] args) {Thread t = new MyThread();System.out.println(t.getState());t.start();try {t.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(t.getState());} }

Interrupt 的含義

當 catch 到 InterruptedException 時,應該在邏輯中寫好處理方式:讓線程停止或者繼續運行

Syncronized 復習

給一個變量/一段代碼加鎖的含義是:線程拿到鎖之后,才能修改一個變量/執行一段代碼

/*** synchronized關鍵字* 對某個對象加鎖*/package com.mashibing.juc.c_001;public class T {private int count = 10;private Object o = new Object();public void m() {synchronized(o) { //任何線程要執行下面的代碼,必須先拿到o的鎖count--;System.out.println(Thread.currentThread().getName() + " count = " + count);}} } /*** synchronized關鍵字* 對某個對象加鎖* @author mashibing*/package com.mashibing.juc.c_002;public class T {private int count = 10;public void m() {synchronized(this) { //任何線程要執行下面的代碼,必須先拿到this的鎖count--;System.out.println(Thread.currentThread().getName() + " count = " + count);}} } /*** synchronized關鍵字* 對某個對象加鎖* @author mashibing*/package com.mashibing.juc.c_003;public class T {private int count = 10;public synchronized void m() { //等同于在方法的代碼執行時要synchronized(this)count--;System.out.println(Thread.currentThread().getName() + " count = " + count);} } /*** synchronized關鍵字* 對某個對象加鎖* @author mashibing*/package com.mashibing.juc.c_004;public class T {private static int count = 10;public synchronized static void m() { //這里等同于synchronized(FineCoarseLock.class)count--;System.out.println(Thread.currentThread().getName() + " count = " + count);}public static void mm() {synchronized(T.class) { //考慮一下這里寫synchronized(this)是否可以?count --;}} }

測試將syncronized方法和非syncronized方法一起調用:非syncronized方法并沒有被阻塞

/*** 同步和非同步方法是否可以同時調用?* @author mashibing*/package com.mashibing.juc.c_007;public class T {public synchronized void m1() { System.out.println(Thread.currentThread().getName() + " m1 start...");try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " m1 end");}public void m2() {try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " m2 ");}public static void main(String[] args) {T t = new T();/*new Thread(()->t.m1(), "t1").start();new Thread(()->t.m2(), "t2").start();*/new Thread(t::m1, "t1").start();new Thread(t::m2, "t2").start();/*//1.8之前的寫法new Thread(new Runnable() {@Overridepublic void run() {t.m1();}});*/ } }

示例:臟讀

/*** 面試題:模擬銀行賬戶* 對業務寫方法加鎖* 對業務讀方法不加鎖* 這樣行不行?** 容易產生臟讀問題(dirtyRead)*/package com.mashibing.juc.c_008;import java.util.concurrent.TimeUnit;public class Account {String name;double balance;public synchronized void set(String name, double balance) {this.name = name;try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}this.balance = balance;}public /*synchronized*/ double getBalance(String name) {return this.balance;}public static void main(String[] args) {Account a = new Account();new Thread(()->a.set("zhangsan", 100.0)).start();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(a.getBalance("zhangsan"));try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(a.getBalance("zhangsan"));} }

總結

以上是生活随笔為你收集整理的多线程与高并发(一):单机高并发应该掌握的线程基础:线程状态,异常与锁等的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。