它會將目前在執行的執行緒使用權限讓出來,交給後續的執行緒繼續執行
會讓執行緒停在runnable等排班器呼叫它執行running
// Main.java
public class Main {
public static void main(String[] args){
System.out.println("main Thread start");
//
Thread thread1 = new Thread(new TestThread("thread1"));
Thread thread2 = new Thread(new TestThread("thread2"));
Thread thread3 = new Thread(new TestThread("thread3"));
thread1.start();
thread2.start();
thread3.start();
System.out.println("main thread end");
}
}
// TestThread.java
public class TestThread implements Runnable {
private String name;
public TestThread(String name){
this.name = name;
}
public void run(){
System.out.println(name + " start");
if ("thread1".equals(name))
Thread.yield();
System.out.println(name + " Running");
System.out.println(name + " end");
}
}
可以指定停止的時間(以毫秒為單位),可以指定執行緒等待多久,時間到了就會開始繼續進行
會讓執行緒停在block狀態,直到時間到了以後,才可以進到runnable
// Main.java
public class Main {
public static void main(String[] args){
System.out.println("main Thread start");
//
Thread thread1 = new Thread(new TestThread("thread1"));
Thread thread2 = new Thread(new TestThread("thread2"));
Thread thread3 = new Thread(new TestThread("thread3"));
thread1.start();
thread2.start();
thread3.start();
System.out.println("main thread end");
}
}
// TestThread.java
public class TestThread implements Runnable {
private String name;
public TestThread(String name){
this.name = name;
}
public void run(){
System.out.println(name + " start");
if ("thread1".equals(name)) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println(name + " Running");
System.out.println(name + " end");
}
}
可以看到thread1第一個開始,但是卻是最後一個結束
可以讓其他的執行緒先執行完它再去接著執行,它必須要等到插隊的執行緒執行完,才可接續執行
// Main.java
public class Main {
public static void main(String[] args){
System.out.println("main Thread start");
Thread thread1 = new Thread(new TestThread("thread1"));
thread1.start();
System.out.println("main thread end");
}
}
// TestThread.java
public class TestThread implements Runnable {
private String name;
public TestThread(String name){
this.name = name;
}
public void run(){
System.out.println(name + " start");
if ("thread1".equals(name)) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println(name + " Running");
System.out.println(name + " end");
}
}
thread1會晚一秒才開始執行,所以我們嘗試加入join()
// Main.java
public class Main {
public static void main(String[] args){
System.out.println("main Thread start");
Thread thread1 = new Thread(new TestThread("thread1"));
thread1.start();
try {
thread1.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("main thread end");
}
}
加入join之後,我們的main方法就會等thread1結束才結束
多執行緒在使用同一個資料時會出現資料不一致的狀況
因為多執行緒的執行時間不一定,所以問題不一定會發生,但還是有機會發生
很多執行緒一起在共用一個物件的時候,有人會塞入資料,有人會讀取資料,這時會變成a執行緒塞入的資料變成b執行緒在使用
在方法加入synchronized這個方法在同一時間只能有一個執行緒使用
我們也能去同步化區塊synchronized(this){...}
另外有一個觀念就是物件的鎖定lock,每一個物件都有一個lock,我們的執行緒要取得lock才能夠執行synchronized裡面的內容
執行緒進入物件等待池等待,等時間到了或是呼叫了notify()
// Main.java
public class Main {
public static void main(String[] args){
System.out.println("main Thread start");
//
Thread thread1 = new Thread(new TestThread("thread1"));
Thread thread2 = new Thread(new TestThread("thread2"));
Thread thread3 = new Thread(new TestThread("thread3"));
thread1.start();
thread2.start();
thread3.start();
System.out.println("main thread end");
}
}
// TestThread.java
public class TestThread implements Runnable {
private String name;
public TestThread(String name){
this.name = name;
}
public void run(){
synchronized (this){
try {
wait(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if ("thread2".equals(name))
notify();
System.out.println(name + " start");
System.out.println(name + " Running");
System.out.println(name + " end");
}
}
}