併發:兩個事件在一個時間段內發生,如單片機的單核多線程java
進程調度:得到CPU使用權的線程才能執行,有分時調度和搶佔式調度兩種多線程
Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec("notepad");
ProcessBuilder pb = new ProcessBuilder("notepad"); pb.start();
一種方法是將類聲明爲 Thread 的子類。該子類應重寫 Thread 類的 run 方法。接下來能夠分配並啓動該子類的實例。併發
//1.建立線程子類,繼承於 Thread 類 //2.覆蓋 Thread 類中的 run 方法{改方法中的代碼稱爲線程執行體} public void run() { System.out.println("1"); } public static void main(String[] args) { //3.在主線程中建立 線程子類對象並啓動 new ThreadDemo().start(); System.out.println("好"); }
class Thread2 implements Runnable { // 1.建立線程子類,繼承於 Thread 類 // 2.覆蓋 Thread 類中的 run 方法{改方法中的代碼稱爲線程執行體} public void run() { System.out.println("使用接口方法"); } } //3.在主線程中建立線程子類對象,把對象做爲參數傳給Thread類,啓動線程 public static void main(String[] args) { Thread2 p = new Thread2(); new Thread(p).start(); }
//(實現接口方式) new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }).start(); //(覆蓋方式) new Thread() { @Override public void run() { // TODO Auto-generated method stub super.run(); } }.start();
繼承方式,建立不是數據的實例,num 必須稱爲全局變量,不然會重複建立堆空間的數據,父類中擁有getname()方法,使用構造器傳入名字參數,便可在子類中獲取名稱ide
package java_study; class People extends Thread { public static int num = 50; public People(String name) { super(name); } public void run() { for (int i = 0; i < num; i++) { System.out.println(super.getName() + "吃了" + num-- + "個蘋果"); } } } public class ThreadExtendsApple { public static void main(String[] args) { new People("小A").start(); new People("小B").start(); new People("小C").start(); } }
使用Apple封裝數據,更加合理科學。使用 Thread 類的靜態方法 currentThread() 獲得當前類的對象,從而獲取對象的名字ui
package java_study; class Apple implements Runnable { public int num = 50; @Override public void run() { for (int i = 0; i < 50; i++) { String name = Thread.currentThread().getName(); if (num > 0) { System.out.println(name + "吃了第" + num-- + "個蘋果"); } } } } public class ThreadImplementApple { public static void main(String[] args) { Apple a = new Apple(); new Thread(a, "A").start(); new Thread(a, "B").start(); new Thread(a, "C").start(); } }