多线程程序设计

写在之前

以下是《Java8编程入门官方教程》中的一些知识,如有错误,烦请指正。涉及的程序如需下载请移步http://down1.tupwk.com.cn/qhwkdownpage/978-7-302-38738-1.zip

多线程

多任务包括:基于进程的多任务和基于线程的多任务。进程是正在执行的程序,相当于计算机允许同时运行多个程序的功能;线程是最小的可分派代码单元,一个程序可以一次执行多个任务,比如文本编辑器可以在打印的同时格式化文本。

单核系统中并发执行的线程共享CPU,每个线程都收到一个CPU时间片;多核系统中,多个线程可以同时执行。多线程的功能在两个系统中都可以实现。

Thread类和Runnable接口

方法 含义
final String getName() 获取线程名
final int getPriority() 获取线程优先级
final boolean isAlive() 确定线程是否仍在运行
final void join() 等待线程终止
static void sleep(long milliseconds) 按照指定的时间挂起线程,以毫秒为单位
void start() 通过调用run方法启动线程
void run() 线程的进入点

线程创建

两种方法:都要用Thread类来实例化、访问、控制线程,仅仅是创建不同。

  1. 实现Runnable接口
  2. 扩展Thread类

比较:一般仅在通过某些方式增强或者修改类的时候才扩展这些类,因此如果不重写Thread的任何其他方法,最好事先Runnable接口。另外实现Runnable接口可以让线程继承除Thread类外的其他类。

Runnable接口只定义了run方法,在run方法中可以调用其他方法,使用其他类,像主线程一样声明变量。具体的方法通过程序来说明。

// 通过实现Runnable接口创建进程
class MyThread implements Runnable {
  String thrdName;

  MyThread(String name) {
    thrdName = name;
  }

  // Entry point of thread.
  public void run() {
    System.out.println(thrdName + " starting.");
    try {
      for(int count=0; count < 10; count++) {
        Thread.sleep(400);
        System.out.println("In " + thrdName +
                           ", count is " + count);
      }
    }
    catch(InterruptedException exc) {
      System.out.println(thrdName + " interrupted.");
    }
    System.out.println(thrdName + " terminating.");
  }
}

class UseThreads {
  public static void main(String args[]) {
    System.out.println("Main thread starting.");

    // 1.创建一个可运行的线程对象
    MyThread mt = new MyThread("Child #1");

    // 2.在该对象上构造一个线程
    Thread newThrd = new Thread(mt);

    // 3.开始运行线程
    newThrd.start();

    for(int i=0; i<50; i++) {
      System.out.print(".");
      try {
        Thread.sleep(100);//主线程main延迟了5秒,线程mt延迟了4秒,确保main在mt结束之后才终止
      }
      catch(InterruptedException exc) {
        System.out.println("Main thread interrupted.");
      }
    }

    System.out.println("Main thread ending.");
  }
}

改进:MyThread类没必要存储线程名,可以在创建时就为其命名。Thread(Runnable threadob, String name)

//改进版
class MyThread implements Runnable {
  Thread thrd;

  // 建立一个新进程
  MyThread(String name) {
    thrd = new Thread(this, name);//创建时就命名
    thrd.start(); // 开始进程
  }

  // Begin execution of new thread.
  public void run() {
    System.out.println(thrd.getName() + " starting.");
    try {
      for(int count=0; count<10; count++) {
        Thread.sleep(400);
        System.out.println("In " + thrd.getName() +
                           ", count is " + count);
      }
    }
    catch(InterruptedException exc) {
      System.out.println(thrd.getName() + " interrupted.");
    }
    System.out.println(thrd.getName() + " terminating.");
  }
}

class UseThreadsImproved {
  public static void main(String args[]) {
    System.out.println("Main thread starting.");

    MyThread mt = new MyThread("Child #1");s//改进后创建时就启动进程

    for(int i=0; i < 50; i++) {
      System.out.print(".");
      try {
        Thread.sleep(100);
      }
      catch(InterruptedException exc) {
        System.out.println("Main thread interrupted.");
      }
    }

    System.out.println("Main thread ending.");
  }
}

另一种方法:扩展Thread,必须重写作为新建成进入点的run方法。

class MyThread extends Thread {

  // 建立一个新的线程.
  MyThread(String name) {
    super(name); // 线程命名
    start(); // 开始线程
  }

  // 线程运行
  public void run() {
    System.out.println(getName() + " starting.");
    try {
      for(int count=0; count < 10; count++) {
        Thread.sleep(400);
        System.out.println("In " + getName() +
                           ", count is " + count);
      }
    }
    catch(InterruptedException exc) {
      System.out.println(getName() + " interrupted.");
    }

    System.out.println(getName() + " terminating.");
  }
}

class ExtendThread {
  public static void main(String args[]) {
    System.out.println("Main thread starting.");

    MyThread mt = new MyThread("Child #1");

    for(int i=0; i < 50; i++) {
      System.out.print(".");
      try {
        Thread.sleep(100);
      }
      catch(InterruptedException exc) {
        System.out.println("Main thread interrupted.");
      }
    } 

    System.out.println("Main thread ending.");
  }
}

创建多个线程

class MyThread implements Runnable {
  Thread thrd;

  // 构造线程
  MyThread(String name) {
    thrd = new Thread(this, name);

    thrd.start(); // 开始线程
  }

  // 执行线程
  public void run() {
    System.out.println(thrd.getName() + " starting.");
    try {
      for(int count=0; count < 10; count++) {
        Thread.sleep(400);
        System.out.println("In " + thrd.getName() +
                           ", count is " + count);
      }
    }
    catch(InterruptedException exc) {
      System.out.println(thrd.getName() + " interrupted.");
    }
    System.out.println(thrd.getName() + " terminating.");
  }
}

class MoreThreads {
  public static void main(String args[]) {
    System.out.println("Main thread starting.");

    MyThread mt1 = new MyThread("Child #1");//创建并开始执行3个线程
    MyThread mt2 = new MyThread("Child #2");
    MyThread mt3 = new MyThread("Child #3");

    for(int i=0; i < 50; i++) {
      System.out.print(".");
      try {
        Thread.sleep(100);
      }
      catch(InterruptedException exc) {
        System.out.println("Main thread interrupted.");
      }
    } 

    System.out.println("Main thread ending.");
  }
}

确定线程的结束

两种方法:

final boolean isAlive()

class MoreThreads { 
  public static void main(String args[]) { 
    System.out.println("Main thread starting."); 
 
    MyThread mt1 = new MyThread("Child #1"); 
    MyThread mt2 = new MyThread("Child #2"); 
    MyThread mt3 = new MyThread("Child #3"); 
 
    do { 
      System.out.print("."); 
      try { 
        Thread.sleep(100); 
      } 
      catch(InterruptedException exc) { 
        System.out.println("Main thread interrupted."); 
      } 
    } while (mt1.thrd.isAlive() || 
             mt2.thrd.isAlive() || 
             mt3.thrd.isAlive()); //使用Alive等待所有线程终止
 
    System.out.println("Main thread ending."); 
  } 
}

final void join() Throws InterruptedException

等待,直到调用的线程终止

class MyThread implements Runnable {
  Thread thrd;

  // Construct a new thread.
  MyThread(String name) {
    thrd = new Thread(this, name);
    thrd.start(); // start the thread
  }

  // Begin execution of new thread.
  public void run() {
    System.out.println(thrd.getName() + " starting.");
    try {
      for(int count=0; count < 10; count++) {
        Thread.sleep(400);
        System.out.println("In " + thrd.getName() +
                           ", count is " + count);
      }
    }
    catch(InterruptedException exc) {
      System.out.println(thrd.getName() + " interrupted.");
    }
    System.out.println(thrd.getName() + " terminating.");
  }
}

class JoinThreads {
  public static void main(String args[]) {
    System.out.println("Main thread starting.");

    MyThread mt1 = new MyThread("Child #1");
    MyThread mt2 = new MyThread("Child #2");
    MyThread mt3 = new MyThread("Child #3");

    try {
      mt1.thrd.join();//等待,直到线程中终结,下同
      System.out.println("Child #1 joined.");
      mt2.thrd.join();
      System.out.println("Child #2 joined.");
      mt3.thrd.join();
      System.out.println("Child #3 joined.");
    }
    catch(InterruptedException exc) {
      System.out.println("Main thread interrupted.");
    }
    System.out.println("Main thread ending.");
  }
}

线程优先级

可以通过Thread的成员方法来修改线程的优先级。

final void setPriority(int level)

level的值必须在MIN_PRIORITYMAX_PRIORITY的范围内,即1-10.优先级定义为static final变量。

可以通过Thread的成员方法获取当前优先级设置。

final int getPriority

//线程的优先级
class Priority implements Runnable { 
  int count; 
  Thread thrd; 
 
  static boolean stop = false; 
  static String currentName; 
 
  /* Construct a new thread. Notice that this  
     constructor does not actually start the 
     threads running. */ 
  Priority(String name) { 
    thrd = new Thread(this, name); 
    count = 0; 
    currentName = name; 
  } 
 
  // Begin execution of new thread. 
  public void run() { 
    System.out.println(thrd.getName() + " starting."); 
    do { 
      count++; 
 
      if(currentName.compareTo(thrd.getName()) != 0) { 
        currentName = thrd.getName(); 
        System.out.println("In " + currentName); 
      } 
 
    } while(stop == false && count < 10000000); 
    stop = true; 
 
    System.out.println("\n" + thrd.getName() + 
                       " terminating."); 
  }
} 


class PriorityDemo { 
  public static void main(String args[]) { 
    Priority mt1 = new Priority("High Priority"); 
    Priority mt2 = new Priority("Low Priority"); 
 
    // set the priorities 
    mt1.thrd.setPriority(Thread.NORM_PRIORITY+2); 
    mt2.thrd.setPriority(Thread.NORM_PRIORITY-2); 
 
    // start the threads 
    mt1.thrd.start(); 
    mt2.thrd.start(); 
 
    try { 
      mt1.thrd.join(); //等待线程结束
      mt2.thrd.join(); 
    } 
    catch(InterruptedException exc) { 
      System.out.println("Main thread interrupted."); 
    } 
 
    System.out.println("\nHigh priority thread counted to " + 
                       mt1.count); 
    System.out.println("Low priority thread counted to " + 
                       mt2.count); 
  } 
}

同步

同步:控制对象访问的监视器,监视器通过实现“锁”来工作。当一个对象被一个线程锁住后,其他线程就不能访问该对象。当该线程退出时,要为对象解锁,使其他进程可以访问他。有两种同步的方法。

通过synchronized关键字修改方法来同步对方法的访问。当调用方法时,调用线程进入对象监视器,对象监视器锁住对象。对象被锁的同时,其他线程不能进入方法,也不能进入対象定义的其他同步方法。当线程从方法返回时,监视器为对象解锁,允许下一个进程使用对象。

//使用同步方法控制访问
class SumArray { 
  private int sum; 
 
  synchronized int sumArray(int nums[]) { //sumArray()被同步
    sum = 0; // reset sum 
 
    for(int i=0; i<nums.length; i++) { 
      sum += nums[i]; 
      System.out.println("Running total for " + 
             Thread.currentThread().getName() + 
             " is " + sum); 
      try { 
        Thread.sleep(10); // allow task-switch 
      } 
      catch(InterruptedException exc) { 
        System.out.println("Thread interrupted."); 
      } 
    } 
    return sum; 
  } 
}  
 
class MyThread implements Runnable { 
  Thread thrd; 
  static SumArray sa = new SumArray(); 
  int a[]; 
  int answer; 
 
  // Construct a new thread. 
  MyThread(String name, int nums[]) { 
    thrd = new Thread(this, name); 
    a = nums; 
    thrd.start(); // start the thread 
  } 
 
  // Begin execution of new thread. 
  public void run() { 
    int sum; 
 
    System.out.println(thrd.getName() + " starting."); 
 
    answer = sa.sumArray(a);          
    System.out.println("Sum for " + thrd.getName() + 
                       " is " + answer); 
 
    System.out.println(thrd.getName() + " terminating."); 
  } 
} 
 
class Sync { 
  public static void main(String args[]) { 
    int a[] = {1, 2, 3, 4, 5}; 
 
    MyThread mt1 = new MyThread("Child #1", a); 
    MyThread mt2 = new MyThread("Child #2", a); 

    try {
      mt1.thrd.join();
      mt2.thrd.join();
    }
    catch(InterruptedException exc) {
      System.out.println("Main thread interrupted.");
    }

  } 
} 

当上面提出的方法在无法访问源代码时,可以将对这种类定义的方法的调用放入synchronized代码块中。

// Use a synchronized block to control access to SumArray.  
class SumArray {  
  private int sum;  
  
  int sumArray(int nums[]) {  //没有同步!!
    sum = 0; // reset sum  
  
    for(int i=0; i<nums.length; i++) {  
      sum += nums[i];  
      System.out.println("Running total for " +  
             Thread.currentThread().getName() +  
             " is " + sum);  
      try {  
        Thread.sleep(10); // allow task-switch  
      }  
      catch(InterruptedException exc) {  
        System.out.println("Thread interrupted.");  
      }  
    }  
    return sum; 
  }  
}   
  
class MyThread implements Runnable {  
  Thread thrd;  
  static SumArray sa = new SumArray();  
  int a[];  
  int answer; 
 
  // Construct a new thread.  
  MyThread(String name, int nums[]) {  
    thrd = new Thread(this, name);  
    a = nums;  
    thrd.start(); // start the thread  
  }  
  
  // Begin execution of new thread.  
  public void run() {  
    int sum;  
  
    System.out.println(thrd.getName() + " starting.");  
  
    // synchronize calls to sumArray()  
    synchronized(sa) {  //对sumArray的调用被同步
      answer = sa.sumArray(a);           
    }  
    System.out.println("Sum for " + thrd.getName() +  
                       " is " + answer);  
  
    System.out.println(thrd.getName() + " terminating.");  
  }  
}  
  
class Sync {  
  public static void main(String args[]) {  
    int a[] = {1, 2, 3, 4, 5};  
  
    MyThread mt1 = new MyThread("Child #1", a);  
    MyThread mt2 = new MyThread("Child #2", a);  
  
    try {  
      mt1.thrd.join();  
      mt2.thrd.join();  
    } catch(InterruptedException exc) {  
      System.out.println("Main thread interrupted.");  
    }  
  }  
} 

线程通信

一个线程可以通知另一个线程它被阻塞,而其他进程也可以通知它继续执行。Java使用wait()notify()notifyAll()支持进程间通信。三个方法是Object类实现的,是所有对象的一部分,只能在同步环境中被调用。当一个线程暂时阻塞无法运行,它调用wait(),导致进程睡眠,对象的监视器被释放,允许其他线程使用该对象。过一段时间后,当另一个线程进入这个监视器的时候,调用notify()notifyAll(),睡眠进程被唤醒。

final void wait() throws InterruptedException//等待,直到被通知
final void wait(long millis) throws InterruptedException//或者等待一定时间后
final void wait(long millis,int nanos) throws InterruptedException
  
final void notify()     //恢复一个等待线程
final void notifyAll()  //通知所有线程

一个使用wait()和notify()的例子

//比较难,请多次阅读或者运行
class TickTock { 

  String state; // contains the state of the clock
 
  synchronized void tick(boolean running) { 
    if(!running) { // stop the clock 
      state = "ticked";
      notify(); // notify any waiting threads 
      return; 
    } 
 
    System.out.print("Tick "); 

    state = "ticked"; // set the current state to ticked

    notify(); // let tock() run 
    try { 
      while(!state.equals("tocked"))
        wait(); // wait for tock() to complete 
    } 
    catch(InterruptedException exc) { 
      System.out.println("Thread interrupted."); 
    } 
  } 
 
  synchronized void tock(boolean running) { 
    if(!running) { // stop the clock 
      state = "tocked";
      notify(); // notify any waiting threads 
      return; 
    } 
 
    System.out.println("Tock"); 

    state = "tocked"; // set the current state to tocked

    notify(); // let tick() run 
    try { 
      while(!state.equals("ticked"))
        wait(); // wait for tick to complete 
    } 
    catch(InterruptedException exc) { 
      System.out.println("Thread interrupted."); 
    } 
  } 
}  
 
class MyThread implements Runnable { 
  Thread thrd; 
  TickTock ttOb; 
 
  // Construct a new thread. 
  MyThread(String name, TickTock tt) { 
    thrd = new Thread(this, name); 
    ttOb = tt; 
    thrd.start(); // start the thread 
  } 
 
  // Begin execution of new thread. 
  public void run() { 
 
    if(thrd.getName().compareTo("Tick") == 0) { 
      for(int is
    } 
  } 
} 
 
class ThreadCom { 
  public static void main(String args[]) { 
    TickTock tt = new TickTock(); 
    MyThread mt1 = new MyThread("Tick", tt); 
    MyThread mt2 = new MyThread("Tock", tt); 
 
    try { 
      mt1.thrd.join(); 
      mt2.thrd.join(); 
    } catch(InterruptedException exc) { 
      System.out.println("Main thread interrupted."); 
    } 
  } 
}

死锁:一个线程等待另一个线程来做某事,而后者却又在等待前者。这就像两个过于礼貌的谦谦君子,都坚持让对方先通过大门。

竞争:当两个或多个线程尝试同时访问共享资源,但是没有进行合适的同步时,就会发生竞争条件。

挂起、继续执行、停止

一个标志变量用于设置挂起和继续执行,分别是:suspendrunning

一个标志变量用于停止,设置为stop

//挂起、继续执行、停止
class MyThread implements Runnable {  
  Thread thrd;  
  boolean suspended;  //当设置为true时挂起线程
  boolean stopped;  //当设置为true时终止线程
    
  MyThread(String name) {  
    thrd = new Thread(this, name);  
    suspended = false;  
    stopped = false; 
    thrd.start();  
  }  
  
  // This is the entry point for thread.  
  public void run() {  
    System.out.println(thrd.getName() + " starting."); 
    try {  
      for(int i = 1; i < 1000; i++) {  
        System.out.print(i + " ");  
        if((i%10)==0) { 
          System.out.println(); 
          Thread.sleep(250); 
        } 
 
        // Use synchronized block to check suspended and stopped. 
        synchronized(this) {  
          while(suspended) {  
            wait();
          }  
          if(stopped) break; 
        }  
      } 
    } catch (InterruptedException exc) {  
      System.out.println(thrd.getName() + " interrupted.");  
    }  
    System.out.println(thrd.getName() + " exiting.");  
  }  
 
  // Stop the thread.  
  synchronized void mystop() {  
    stopped = true;  
 
   // The following ensures that a suspended thread can be stopped. 
    suspended = false; 
    notify(); 
  }  
 
  // Suspend the thread. 
  synchronized void mysuspend() {++++++++++
    suspended = true;  
  }  
 
  // Resume the thread.  
  synchronized void myresume() { 
    suspended = false;  
    notify();  
  }  
}  
  
class Suspend {  
  public static void main(String args[]) {  
    MyThread ob1 = new MyThread("My Thread");  
 
    try {  
      Thread.sleep(1000); // let ob1 thread start executing 
  
      ob1.mysuspend();  
      System.out.println("Suspending thread.");  
      Thread.sleep(1000); 
 
      ob1.myresume();  
      System.out.println("Resuming thread.");  
      Thread.sleep(1000); 
 
 
      ob1.mysuspend();  
      System.out.println("Suspending thread.");  
      Thread.sleep(1000); 
 
      ob1.myresume();  
      System.out.println("Resuming thread.");  
      Thread.sleep(1000); 
 
      ob1.mysuspend();  
      System.out.println("Stopping thread."); 
      ob1.mystop(); 
    } catch (InterruptedException e) {  
      System.out.println("Main thread Interrupted");  
    }  
  
    // wait for thread to finish  
    try {  
      ob1.thrd.join();  
    } catch (InterruptedException e) {  
      System.out.println("Main thread Interrupted");  
    }  
   
    System.out.println("Main thread exiting.");  
  }  
}

主线程

class UseMain { 
  public static void main(String args[]) { 
    Thread thrd; 
 
    // Get the main thread. 
    thrd = Thread.currentThread(); 
 
    // Display main thread's name. 
    System.out.println("Main thread is called: " + 
                       thrd.getName()); 
 
    // Display main thread's priority. 
    System.out.println("Priority: " + 
                       thrd.getPriority()); 
 
    System.out.println(); 
 
    // Set the name and priority. 
    System.out.println("Setting name and priority.\n"); 
    thrd.setName("Thread #1"); 
    thrd.setPriority(Thread.NORM_PRIORITY+3); 
 
    System.out.println("Main thread is now called: " + 
                       thrd.getName()); 
 
    System.out.println("Priority is now: " + 
                       thrd.getPriority()); 
  } 
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,565评论 18 399
  • 本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 首先讲...
    李欣阳阅读 2,438评论 1 15
  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 2,949评论 1 18
  • 一直挺喜欢云 一直忙于事物 一直想拍一片自己的天空 我想,我可以。 我想展示自己的世界 我想分享我的快乐 (ps...
    清霜寒露阅读 153评论 0 3
  • 八月,他们都在新生群里憧憬着大学生活。 无意间,他们再次进入了同一个群聊里...同学们都很开朗,群里每天都很热闹。...
    A李哲哲阅读 936评论 1 6