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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

java线程的简单例子(Thread and runnable)

發布時間:2024/4/17 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java线程的简单例子(Thread and runnable) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://interper56-sohu-com.iteye.com/blog/172303

其實要了解java多線程只需要理解以下幾個事情:
1) java.lang.Thraed類
2) java.lang.Runnable接口
3) synchronized關鍵字
4) wait(),.notify(), notifyAll();

That’s all.

[java.util.Thread類]
Jdk的線程實現類,只要繼承這個類那么我們就可以實現自己的線程。
如果你想要繼承這個類,主要需要重載run方法。

例如:
Java代碼 ?
  • Pubilc?class?MyThread?{ ??
  • ????Pubilc?MyThread()?{ ??
  • ????????Super(); ??
  • ????} ??
  • ??
  • ????Public?void?run()?{ ??
  • ????????System.out.println(“Hello?world”); ??
  • ????} ??
  • }??
  • Pubilc class MyThread {Pubilc MyThread() {Super();}Public void run() {System.out.println(“Hello world”);} }

    當你要是用它的時候
    Java代碼 ?
  • Publi?class?ThreadTest?{ ??
  • ????Public?static?void?main(String[]?args)??{ ??
  • ????????MyThread?app?=?new?MyThread(); ??
  • ????????App.start(); ??
  • ????} ??
  • }??
  • Publi class ThreadTest {Public static void main(String[] args) {MyThread app = new MyThread();App.start();} }

    當你運行這個方法的時候,就會打出Hello world.

    [java.lang.Runnable接口]
    因為繼承Thread類就無法繼承別的你想要變為線程的類,
    所以java.lang.Runnable接口可以實現你的愿望

    那么看下面的例子:
    食物類:
    Java代碼 ?
  • public?class?Food?{ ??
  • ????private?int?foodNum?=?0; ??
  • ??
  • ????public?Food(int?foodNum)?{ ??
  • ????????this.foodNum?=?foodNum; ??
  • ????} ??
  • ???? ??
  • ????public?void?setFoodNum(int?foodNum)?{ ??
  • ????????this.foodNum?=?foodNum; ??
  • ????} ??
  • ???? ??
  • ????public?int?getFoodNum()?{ ??
  • ????????return?this.foodNum; ??
  • ????} ??
  • }??
  • public class Food {private int foodNum = 0;public Food(int foodNum) {this.foodNum = foodNum;}public void setFoodNum(int foodNum) {this.foodNum = foodNum;}public int getFoodNum() {return this.foodNum;} }
    消費者類:
    Java代碼 ?
  • public?class?Customer?{ ??
  • ????private?String?name?=?""; ??
  • ??
  • ????public?Customer(String?name)?{ ??
  • ????????this.setName(name); ??
  • ????} ??
  • ??
  • ????protected?void?setName(String?name)?{ ??
  • ????????this.name?=?name; ??
  • ????} ??
  • ??
  • ????protected?String?getName()?{ ??
  • ????????return?this.name; ??
  • ????} ??
  • }??
  • public class Customer {private String name = "";public Customer(String name) {this.setName(name);}protected void setName(String name) {this.name = name;}protected String getName() {return this.name;} }
    消費者線程類:
    Java代碼 ?
  • public?class?CustomerThread?extends?Customer?implements?Runnable?{ ??
  • ??
  • ????private?Food?food?=?null; ??
  • ??
  • ????public?CustomerThread(Food?food)?{ ??
  • ????????super("Customer"); ??
  • ????????this.food?=?food; ??
  • ????} ??
  • ??
  • ????public?void?run()?{ ??
  • ????????this.consume(); ??
  • ????} ??
  • ???? ??
  • ????public?void?startConsume()?{ ??
  • ????????Thread?thread?=?new?Thread(this); ??
  • ????????thread.start(); ??
  • ????} ??
  • ??
  • ????private?void?consume()?{ ??
  • ????????int?num?=?this.food.getFoodNum(); ??
  • ????????num++; ??
  • ????????this.food.setFoodNum(num); ??
  • ????????System.out.println(this.getName()?+?"?"?+?"consume?food"); ??
  • ????} ??
  • }??
  • public class CustomerThread extends Customer implements Runnable {private Food food = null;public CustomerThread(Food food) {super("Customer");this.food = food;}public void run() {this.consume();}public void startConsume() {Thread thread = new Thread(this);thread.start();}private void consume() {int num = this.food.getFoodNum();num++;this.food.setFoodNum(num);System.out.println(this.getName() + " " + "consume food");} }
    生產者類:
    Java代碼 ?
  • public?class?Productor?{ ??
  • ????private?String?name?=?""; ??
  • ??
  • ????public?Productor(String?name)?{ ??
  • ????????this.name?=?name; ??
  • ????} ??
  • ??
  • ????protected?void?setName(String?name)?{ ??
  • ????????this.name?=?name; ??
  • ????} ??
  • ??
  • ????protected?String?getName()?{ ??
  • ????????return?this.name; ??
  • ????} ??
  • }??
  • public class Productor {private String name = "";public Productor(String name) {this.name = name;}protected void setName(String name) {this.name = name;}protected String getName() {return this.name;} }
    消費者類:
    Java代碼 ?
  • public?class?ProductorThread?extends?Productor?implements?Runnable?{ ??
  • ??
  • ????private?Food?food?=?null; ??
  • ???? ??
  • ????public?ProductorThread(Food?food)?{ ??
  • ????????super("Productor"); ??
  • ????????this.food?=?food; ??
  • ????} ??
  • ??
  • ???? ??
  • ????public?void?run()?{ ??
  • ????????this.increase(); ??
  • ????} ??
  • ???? ??
  • ????public?void?startIncrease()?{ ??
  • ????????Thread?thread?=?new?Thread(this); ??
  • ????????thread.start(); ??
  • ????} ??
  • ??
  • ????private?void?increase()?{ ??
  • ????????int?num?=?this.food.getFoodNum(); ??
  • ????????num--; ??
  • ????????this.food.setFoodNum(num); ??
  • ????????System.out.println(this.getName()?+?"?"?+?"increase?food"); ??
  • ????} ??
  • }??
  • public class ProductorThread extends Productor implements Runnable {private Food food = null;public ProductorThread(Food food) {super("Productor");this.food = food;}public void run() {this.increase();}public void startIncrease() {Thread thread = new Thread(this);thread.start();}private void increase() {int num = this.food.getFoodNum();num--;this.food.setFoodNum(num);System.out.println(this.getName() + " " + "increase food");} }

    測試類:
    Java代碼 ?
  • public?class?MainTest?{ ??
  • ????public?static?void?main(String[]?args)?{ ??
  • ????????Food?food?=?new?Food(0); ??
  • ????????ProductorThread?productor?=?new?ProductorThread(food); ??
  • ????????productor.startIncrease(); ??
  • ????????CustomerThread?customer?=?new?CustomerThread(food); ??
  • ????????customer.startConsume(); ??
  • ????} ??
  • }??
  • public class MainTest {public static void main(String[] args) {Food food = new Food(0);ProductorThread productor = new ProductorThread(food);productor.startIncrease();CustomerThread customer = new CustomerThread(food);customer.startConsume();} }

    上面代碼主要模擬了生產者和消費者生產食物,消費食物的過程,
    這里面先讓生產者生產了1個食物,然后讓消費者消費了1個食物。

    主要是想說明我們自己實現的Runnable接口的類必須借助Thread類
    才可以把它變成一個線程,如果不借助Thread類,即使我們實現了run()方法,
    這個類的對象也不會是一個線程。
    說白了,就是用Thread(Runnable thread)這個構造方法把我們實現的Runnable
    街口的類傳入,然后通過Thread的start方法,來調用我們的run方法,其實
    我們實現的Runnable接口的類要想變為線程,是要通過Thread這個載體來實現。

    但是上面的實現存在一個問題,我們并不能保證同一時間內只有一個
    CustomerThread線程在消費,不能保證在同一時間只有一個ProductorThread
    線程在生產。

    所以我們引入了synchronized關鍵字

    [synchronized關鍵字]
    通過在CustomerThraed的consume方法和ProductorThread的increase
    方法前面加入synchronized關鍵字就可以解決上面所說的問題。
    改動后的方法為:
    Java代碼 ?
  • private?synchronized?void?consume()?{ ??
  • ????int?num?=?this.food.getFoodNum(); ??
  • ????num++; ??
  • ????this.food.setFoodNum(num); ??
  • ????System.out.println(this.getName()?+?"?"?+?"consume?food"); ??
  • } ??
  • private?synchronized?void?increase()?{ ??
  • ????int?num?=?this.food.getFoodNum(); ??
  • ????num--; ??
  • ????this.food.setFoodNum(num); ??
  • ????System.out.println(this.getName()?+?"?"?+?"increase?food"); ??
  • }??
  • private synchronized void consume() {int num = this.food.getFoodNum();num++;this.food.setFoodNum(num);System.out.println(this.getName() + " " + "consume food");}private synchronized void increase() {int num = this.food.getFoodNum();num--;this.food.setFoodNum(num);System.out.println(this.getName() + " " + "increase food");}
    那么synchronized關鍵字到底是干什么用的呢?

    就是進入到synchronized關鍵字所包含的代碼塊的線程
    都會嘗試獲得對象的鎖,等拿到對象的鎖后就可以進去執行代碼,
    如果得不到,就在那里阻塞,等待其它線程釋放鎖,那么怎么用呢?

    1)在方法前用synchronized關鍵字,如下:
    Java代碼 ?
  • private?synchronized?void?consume()?{ ??
  • ????int?num?=?this.food.getFoodNum(); ??
  • ????num++; ??
  • ????this.food.setFoodNum(num); ??
  • ????System.out.println(this.getName()?+?"?"?+?"consume?food"); ??
  • }??
  • private synchronized void consume() {int num = this.food.getFoodNum();num++;this.food.setFoodNum(num);System.out.println(this.getName() + " " + "consume food");}

    當線程進入到這個方法的時候,這個線程就會獲得這個方法所在對象的鎖,
    那么其他的進程想要進入這個方法,首先嘗試去獲得這個方法所在對象的鎖,
    但是已經被前一個線程霸占了,所只能等待,當前一個線程把這段代碼執行
    完畢,那么后來的線程就可以獲得這個對象鎖了,當然它進去后又會把后面的
    線程阻塞在外面等待。
    這種方法等同于:
    Java代碼 ?
  • private?void?consume()?{ ??
  • ????synchronized(this)?{ ??
  • ????????int?num?=?this.food.getFoodNum(); ??
  • ????????num++; ??
  • ????????this.food.setFoodNum(num); ??
  • ????????System.out.println(this.getName()?+?"?"?+?"consume?food"); ??
  • ????} ??
  • }??
  • private void consume() {synchronized(this) {int num = this.food.getFoodNum();num++;this.food.setFoodNum(num);System.out.println(this.getName() + " " + "consume food");}}

    但是這種方法我們把整個對象都鎖住了,其他線程想要執行這個類中的其它用
    Synchronized方法聲明的方法都不可以了,因為想要進入其它的synchronized
    方法也要先獲得這個對象的鎖,所以這種方法比較霸道,我們不建議這么做,
    所以出現了第二種方法。
    2)聲明一個臨時的對象,讓進入同一個方法的線程去獲得這個臨時對象的鎖,
    ? 那么獲得這個臨時對象的鎖,并不是整個對象的鎖,所以并不會鎖住整個對象,
    ? 當然也就避免了上面第一種所遇到的問題:
    Java代碼 ?
  • private?void?consume()?{ ??
  • ????Object?lock?=?new?Object(); ??
  • ????synchronized(lock)?{ ??
  • ????????int?num?=?this.food.getFoodNum(); ??
  • ????????num++; ??
  • ????????this.food.setFoodNum(num); ??
  • ????????System.out.println(this.getName()?+?"?"?+?"consume?food"); ??
  • ????} ??
  • }??
  • private void consume() {Object lock = new Object();synchronized(lock) {int num = this.food.getFoodNum();num++;this.food.setFoodNum(num);System.out.println(this.getName() + " " + "consume food");}}
    Obj是一個臨時的對象,當多個線程進入到這個方法的時候都會嘗試去獲得這個
    Obj對象的鎖,誰先獲得,誰就可以繼續執行,否則阻塞在外面,等待前一個進程
    結束執行synchronized內的代碼,出了synchronized包含的代碼塊之后,
    會馬上自動釋放對這個obj對象的鎖。

    [wait(), notify()和notifyAll()]
    其實采用了上面的synchronized關鍵字之后,上面的代碼還是有問題,
    什么問題?
    我們再來仔細分析一下Synchronzied關鍵字,
    Synchronzied關鍵字對線程來說就是這么一回事:
    1) 線程進入synchronized代碼塊:嘗試獲得對象鎖
    2) 線程出了synchronized代碼塊:釋放對象鎖
    說白了,就是誰有鎖,誰就可以繼續干活,沒有就得等。
    加鎖就是限制同一時間有多個線程同時去訪問公共的資源。

    但是問題也就來了,synchronized可以限制對公共的資源訪問,
    但是無法決定線程訪問公共資源的順序,所以引入了wait(),
    Notify(), notifyAll 等原語來控制線程訪問的順序。
    注意這3個原語是當前對象的方法,不是當前線程的方法。

    那么讓我們來看看這三個原語有什么用:
    1) wait(): 使當前線程阻塞,釋放它所獲得的對象的鎖
    2) notify(): 通知虛擬機當前線程準備要釋放它所獲得的對象的鎖,
    ?????????????? 當調用了wait()方法或者當這個線程出了synchronized
    ?????????????? 代碼塊之后,這兩個動作就是釋放了當前線程對對象的鎖的持有,
    ?????????????? 那么其它的被阻塞的線程又可以執行了。
    3) notify(): 跟notify()沒有什么大區別,notify是通知1個被阻塞的線程做準備,
    ?????????????? notifyAll()是通知所有被阻塞的線程做準備,至于哪個線程可以獲得
    ?????????????? 這個鎖,那就看JVM的啦!

    所以對于上面的生產者與消費者的例子,
    正確的流程是,
    如果消費者有東西可以消費,那么我們就讓他消費,
    如果還需要生產,還可以生產,那么我們就讓生產者生產,
    只需要修改CustomerThread類ProductorThread類,
    Food類 MainTest類。
    那么我們的最終代碼如下:
    CustomerThread類:
    Java代碼 ?
  • public?class?CustomerThread?extends?Customer?implements?Runnable?{ ??
  • ??
  • ????private?Food?food?=?null; ??
  • ??
  • ????public?CustomerThread(Food?food)?{ ??
  • ????????super("Customer"); ??
  • ????????this.food?=?food; ??
  • ????} ??
  • ??
  • ????public?void?run()?{ ??
  • ????????this.consume(); ??
  • ????} ??
  • ???? ??
  • ????public?void?startConsume()?{ ??
  • ????????Thread?thread?=?new?Thread(this); ??
  • ????????thread.start(); ??
  • ????} ??
  • ??
  • ????private?void?consume()?{ ??
  • ????????synchronized(food)?{ ??
  • ????????????while(true)?{ ??
  • ????????????????if(food.getFoodNum()?<=?0)?{ ??
  • ????????????????????try?{ ??
  • ????????????????????????food.wait(); ??
  • ????????????????????}?catch?(InterruptedException?e)?{ ??
  • ????????????????????????//?Do?nothing ??
  • ????????????????????} ??
  • ????????????????}?else?{ ??
  • ????????????????????break; ??
  • ????????????????} ??
  • ????????????} ??
  • ????????????int?num?=?this.food.getFoodNum(); ??
  • ????????????num--; ??
  • ????????????this.food.setFoodNum(num); ??
  • ????????????System.out.println(this.getName()?+?"?"?+?"consume?food?"?+?num); ??
  • ????????????food.notify(); ??
  • ????????} ??
  • ????} ??
  • }??
  • public class CustomerThread extends Customer implements Runnable {private Food food = null;public CustomerThread(Food food) {super("Customer");this.food = food;}public void run() {this.consume();}public void startConsume() {Thread thread = new Thread(this);thread.start();}private void consume() {synchronized(food) {while(true) {if(food.getFoodNum() <= 0) {try {food.wait();} catch (InterruptedException e) {// Do nothing}} else {break;}}int num = this.food.getFoodNum();num--;this.food.setFoodNum(num);System.out.println(this.getName() + " " + "consume food " + num);food.notify();}} }

    ProductorThread類:
    Java代碼 ?
  • public?class?ProductorThread?extends?Productor?implements?Runnable?{ ??
  • ??
  • ????private?Food?food?=?null; ??
  • ???? ??
  • ????public?ProductorThread(Food?food)?{ ??
  • ????????super("Productor"); ??
  • ????????this.food?=?food; ??
  • ????} ??
  • ??
  • ????public?void?run()?{ ??
  • ????????this.increase(); ??
  • ????} ??
  • ???? ??
  • ????public?void?startIncrease()?{ ??
  • ????????Thread?thread?=?new?Thread(this); ??
  • ????????thread.start(); ??
  • ????} ??
  • ??
  • ????private?void?increase()?{ ??
  • ????????synchronized(food)?{ ??
  • ????????????while(true)?{ ??
  • ????????????????if(food.getFoodNum()?==?Food.MAX_NUM)?{ ??
  • ????????????????????try?{ ??
  • ????????????????????????food.wait(); ??
  • ????????????????????}?catch?(InterruptedException?e)?{ ??
  • ????????????????????????//?Do?nothing ??
  • ????????????????????} ??
  • ????????????????}?else?{ ??
  • ????????????????????break; ??
  • ????????????????} ??
  • ????????????} ??
  • ????????????int?num?=?this.food.getFoodNum(); ??
  • ????????????num++; ??
  • ????????????this.food.setFoodNum(num); ??
  • ????????????System.out.println(this.getName()?+?"?"?+?"increase?food?"?+?num); ??
  • ????????????food.notify(); ??
  • ????????} ??
  • ????} ??
  • }??
  • public class ProductorThread extends Productor implements Runnable {private Food food = null;public ProductorThread(Food food) {super("Productor");this.food = food;}public void run() {this.increase();}public void startIncrease() {Thread thread = new Thread(this);thread.start();}private void increase() {synchronized(food) {while(true) {if(food.getFoodNum() == Food.MAX_NUM) {try {food.wait();} catch (InterruptedException e) {// Do nothing}} else {break;}}int num = this.food.getFoodNum();num++;this.food.setFoodNum(num);System.out.println(this.getName() + " " + "increase food " + num);food.notify();}} }

    Food類:
    Java代碼 ?
  • public?class?Food?{ ??
  • ??
  • ????public?static?final?int?MAX_NUM?=?10; ??
  • ??
  • ????private?int?foodNum?=?0; ??
  • ??
  • ????public?Food(int?foodNum)?{ ??
  • ????????this.foodNum?=?foodNum; ??
  • ????} ??
  • ??
  • ????public?void?setFoodNum(int?foodNum)?{ ??
  • ????????this.foodNum?=?foodNum; ??
  • ????} ??
  • ??
  • ????public?int?getFoodNum()?{ ??
  • ????????return?this.foodNum; ??
  • ????} ??
  • }??
  • public class Food {public static final int MAX_NUM = 10;private int foodNum = 0;public Food(int foodNum) {this.foodNum = foodNum;}public void setFoodNum(int foodNum) {this.foodNum = foodNum;}public int getFoodNum() {return this.foodNum;} }

    MainTest類:
    Java代碼 ?
  • public?class?MainTest?{ ??
  • ????public?static?void?main(String[]?args)?{ ??
  • ????????Food?food?=?new?Food(0); ??
  • ???????? ??
  • ????????CustomerThread?customer?=?new?CustomerThread(food); ??
  • ????????customer.startConsume(); ??
  • ????????CustomerThread?customer1?=?new?CustomerThread(food); ??
  • ????????customer1.startConsume(); ??
  • ????????CustomerThread?customer2?=?new?CustomerThread(food); ??
  • ????????customer2.startConsume(); ??
  • ????????CustomerThread?customer3?=?new?CustomerThread(food); ??
  • ????????customer3.startConsume(); ??
  • ????????CustomerThread?customer4?=?new?CustomerThread(food); ??
  • ????????customer4.startConsume(); ??
  • ????????CustomerThread?customer5?=?new?CustomerThread(food); ??
  • ????????customer5.startConsume(); ??
  • ???????? ??
  • ????????ProductorThread?productor?=?new?ProductorThread(food); ??
  • ????????productor.startIncrease(); ??
  • ????????ProductorThread?productor1?=?new?ProductorThread(food); ??
  • ????????productor1.startIncrease(); ??
  • ????????ProductorThread?productor2?=?new?ProductorThread(food); ??
  • ????????productor2.startIncrease(); ??
  • ????????ProductorThread?productor3?=?new?ProductorThread(food); ??
  • ????????productor3.startIncrease(); ??
  • ????????ProductorThread?productor4?=?new?ProductorThread(food); ??
  • ????????productor4.startIncrease(); ??
  • ????????ProductorThread?productor5?=?new?ProductorThread(food); ??
  • ????????productor5.startIncrease(); ??
  • ??
  • ??
  • ??
  • ????} ??
  • }??
  • public class MainTest {public static void main(String[] args) {Food food = new Food(0);CustomerThread customer = new CustomerThread(food);customer.startConsume();CustomerThread customer1 = new CustomerThread(food);customer1.startConsume();CustomerThread customer2 = new CustomerThread(food);customer2.startConsume();CustomerThread customer3 = new CustomerThread(food);customer3.startConsume();CustomerThread customer4 = new CustomerThread(food);customer4.startConsume();CustomerThread customer5 = new CustomerThread(food);customer5.startConsume();ProductorThread productor = new ProductorThread(food);productor.startIncrease();ProductorThread productor1 = new ProductorThread(food);productor1.startIncrease();ProductorThread productor2 = new ProductorThread(food);productor2.startIncrease();ProductorThread productor3 = new ProductorThread(food);productor3.startIncrease();ProductorThread productor4 = new ProductorThread(food);productor4.startIncrease();ProductorThread productor5 = new ProductorThread(food);productor5.startIncrease();} }

    終于寫完了,累死我了~~~
    • 多線程問題.rar (19.1 KB)
    • 描述: 這篇文檔和對應的源代碼
    • 下載次數: 35

    ?

    總結

    以上是生活随笔為你收集整理的java线程的简单例子(Thread and runnable)的全部內容,希望文章能夠幫你解決所遇到的問題。

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