欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java并發(fā)編程專題(二)----如何創(chuàng)建并運(yùn)行java線程

 更新時(shí)間:2020年06月30日 11:33:38   作者:rickiyang  
這篇文章主要介紹了java并發(fā)編程如何創(chuàng)建并運(yùn)行java線程,文中講解非常詳細(xì),示例代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下

實(shí)現(xiàn)線程的兩種方式

上一節(jié)我們了解了關(guān)于線程的一些基本知識(shí),下面我們正式進(jìn)入多線程的實(shí)現(xiàn)環(huán)節(jié)。實(shí)現(xiàn)線程常用的有兩種方式,一種是繼承Thread類,一種是實(shí)現(xiàn)Runnable接口。當(dāng)然還有第三種方式,那就是通過線程池來生成線程,后面我們還會(huì)學(xué)習(xí),一步一個(gè)腳印打好基礎(chǔ)。

Runnable接口:

public interface Runnable {
 public abstract void run();
}

Thread類:

public class Thread implements Runnable {
 public synchronized void start() {  
  if (threadStatus != 0)
   throw new IllegalThreadStateException();  
  group.add(this);
  boolean started = false;
  try {
   start0();
   started = true;
  } finally {
   try {
    if (!started) {
     group.threadStartFailed(this);
    }
   } catch (Throwable ignore) {
    /* do nothing. If start0 threw a Throwable then
     it will be passed up the call stack */
   }
 }
 @Override
 public void run() {
  if (target != null) {
   target.run();
  }
 }
}

上面為Thread類和Runnable類的源碼,我們可以看到Thread類也是實(shí)現(xiàn)了Runnable接口,即Thread是Runnable的實(shí)現(xiàn),那么他們到底在實(shí)現(xiàn)多線程上有什么區(qū)別呢?
Thread和Runnable解析:

(1)Runnable接口:

Runnable接口是java中線程的定義類。所有線程都是通過該接口來實(shí)現(xiàn),該接口中的run()方法為實(shí)現(xiàn)方法,即線程所要實(shí)現(xiàn)的內(nèi)容寫入該方法里面,當(dāng)線程啟動(dòng)時(shí)會(huì)調(diào)用該方法。
在大多數(shù)情況下,如果只想重寫run()方法而不重寫其他方法,應(yīng)使用Runnable接口。

public class ThreadDemo3 {   
 public static void main(String[] args) { 
  //new了兩個(gè)線程對(duì)象——s1和s2
  //其中兩個(gè)對(duì)象各對(duì)應(yīng)一個(gè)內(nèi)存區(qū)域。線程運(yùn)行過程中運(yùn)行都是自己內(nèi)存塊中的數(shù)據(jù)  
  Shop1 s1 = new Shop1("小武");
  s1.start();

  Shop1 s2 = new Shop1("小潘");
  s2.start();   
  /*
  //實(shí)例化了兩個(gè)線程對(duì)象,所以分配了兩塊內(nèi)存空間
  //執(zhí)行過程中操作的是自己的內(nèi)存空間
  Shop2 s3 = new Shop2("小武");
  s3.run();    
  Shop2 s4 = new Shop2("小潘");
  s4.run();   
  //實(shí)際實(shí)例化了兩個(gè)線程對(duì)象
  //所以同樣分配兩個(gè)內(nèi)存空間
  Thread t1 = new Thread(new Shop2("小武"));
  t1.start();

  Thread t2 = new Thread(new Shop2("小潘"));
  t2.start();
  */   
  //創(chuàng)建了兩個(gè)線程對(duì)象,但是使用的是同一個(gè)對(duì)象——s6 
  Shop2 s5 = new Shop2("w");  
  Shop1 s6 = new Shop1("T");
  Thread t3 = new Thread(s6);
  t3.start();

  Thread t4 =new Thread(s6);
  t4.start();      
 }
}

/**
 * 武大郎賣燒餅(因?yàn)闃I(yè)務(wù)的拓展,現(xiàn)在可以實(shí)現(xiàn)多窗口的出售)
 *  要求:每天只賣10個(gè)
 *
 */
class Shop1 extends Thread{
 //private int count = 10;
 //使用靜態(tài)變量可以有效的實(shí)現(xiàn)資源共享(因?yàn)樵趦?nèi)存中只有一份count)
 private static int count = 10;
 public Shop1(String name) {
  super(name);
 }
 public void run(){
  //判斷是否已經(jīng)賣完
  while(count>0){
   count--;
   System.out.println(this.getName() +"賣出了一個(gè)燒餅" + ",現(xiàn)在剩余" + count);
  }
 }
}

/**
 * 使用接口實(shí)現(xiàn)上面的代碼
 *
 */
class Shop2 implements Runnable{
 //私有變量,存儲(chǔ)剩余燒餅的個(gè)數(shù)
 private int count = 10;
 //存儲(chǔ)當(dāng)前人的姓名
 private String name="";

 public Shop2(String name) {
  this.name = name;
 }

 /**
  * 實(shí)現(xiàn)銷售的方法
  */
 public void run(){
  //判斷是否已經(jīng)賣完
  while(count>0){
   count--;
   System.out.println(Thread.currentThread().getId() + "、" + this.name +"賣出了一個(gè)燒餅" + ",現(xiàn)在剩余" + count);
  }
 }
}

(2)Thread類:

Thread類是Runnable接口的實(shí)現(xiàn),jdk給我們提供了一個(gè)不用我們?nèi)ハ肴绾螌?shí)現(xiàn)線程的方式供我們使用。同樣你在繼承Thread類的時(shí)候也需要重寫run()方法來實(shí)現(xiàn)你想在線程中實(shí)現(xiàn)的內(nèi)容。

public class Test{
  public static void main(String[] args) {
    //傳統(tǒng)方式——單任務(wù)方式
    /*
    SimpleClass sc1 = new SimpleClass();
    sc1.say("Mike");

    SimpleClass sc2 = new SimpleClass();
    sc2.say("Han Meimei");
    */
    //創(chuàng)建一個(gè)線程
    ThreadClass tc1 = new ThreadClass("Mike");
    //啟動(dòng)線程
    tc1.start();
    //創(chuàng)建一個(gè)線程
    ThreadClass tc2 = new ThreadClass("Han Meimei");
    tc2.start();

   } 
  }
 }

 class SimpleClass{
  public void say(String name){
   while(true){
    System.out.println("Hi,Im " + name);
   }
  }
 }
 class ThreadClass extends Thread{
  public ThreadClass(String name) {
   super(name);
  }

  /**
   * 將父類(Thread)的run()方法進(jìn)行重寫
   * 在run()方法中包含了需要執(zhí)行的代碼
   */
  public void run(){
   while(true){
    System.out.println("Hi,Im " + this.getName() + "|" + this.getId() + "|" + this.getStackTrace());
   }
  }
 }

Thread類中常用方法:

run():如果該線程時(shí)使用獨(dú)立的Runnable運(yùn)行對(duì)象構(gòu)造的,則調(diào)用該Runnable對(duì)象的run方法。否則,該方法不執(zhí)行任何操作并返回。
sleep(longmillls):在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行),此操作受到系統(tǒng)計(jì)時(shí)器和調(diào)度程序精度和準(zhǔn)確性的影響 String
yield():暫停當(dāng)前正在執(zhí)行的線程對(duì)象,并執(zhí)行其他線程 start():使該線程開始運(yùn)行,java虛擬機(jī)再調(diào)用該線程的run方法
join():等待該線程結(jié)束

對(duì)比:

上面給出了Thread和Runnable的實(shí)現(xiàn),我們能看到在使用Runnable的方式實(shí)現(xiàn)線程的過程中:

 Shop1 s6 = new Shop1("T");
 Thread t3 = new Thread(s6);
 t3.start();

即把Runnable對(duì)象(實(shí)現(xiàn)了Runnable接口的對(duì)象)還是塞進(jìn)了Thread中讓Thread來實(shí)現(xiàn)。那么我們可以new 多個(gè)Thread來實(shí)現(xiàn)同一個(gè)Runnbale對(duì)象,即實(shí)現(xiàn)了資源的共享,比如在售票系統(tǒng)中多名用戶對(duì)同一種票的搶購。另一方面,java是單繼承多實(shí)現(xiàn)的,如果我們使用Thread的話意味著該類只能繼承Thread,對(duì)于程序的擴(kuò)展不利,而實(shí)現(xiàn)Runnbale接口則沒有這個(gè)顧慮??紤]程序的健壯性,我們應(yīng)該盡量使用Runnable來實(shí)現(xiàn)我們的線程。

run和start

初學(xué)多線程我們總是分不清楚run()方法和start()方法的區(qū)別,其實(shí)我們?cè)倏匆幌律厦鎀hread類的源碼就不難發(fā)現(xiàn)他們的用法是很容易區(qū)分的:

  1. run()方法是線程的實(shí)現(xiàn)方法,即你需要線程去做什么事情,那么這些實(shí)現(xiàn)的內(nèi)容寫在run()里面,當(dāng)線程啟動(dòng)時(shí)就會(huì)調(diào)用run()方法繼而實(shí)現(xiàn)run()內(nèi)部的代碼;
  2. start()方法是線程的啟動(dòng)方法,即如果你new Thread()這樣并不算完。你還得new Thread().start()才算啟動(dòng)這個(gè)線程,啟動(dòng)完之后線程內(nèi)部會(huì)主動(dòng)的調(diào)用run()方法執(zhí)行該線程的業(yè)務(wù)邏輯代碼。

以上就是java并發(fā)編程專題(二)----如何創(chuàng)建并運(yùn)行java線程的詳細(xì)內(nèi)容,更多關(guān)于JAVA 創(chuàng)建并運(yùn)行java線程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論