內容
1.線程中的兩個不常用方法介紹
2.線程同步機制初步
一.線程中的兩個不常用方法介紹
1.Thread.yield()
Thread.yield()與sleep()類似,只是不能由用戶指定暫停多長時間,并且yield()方法只能讓同優先級的線程有執行的機會,讓位時間不固定
注意:該方法也是一個靜態方法
2.t.join()
t.join()是線程合并,合并之后就可能變成了單線程的程序。
這一行代碼出現在哪個線程中,t就和哪個線程合并。從這也可以看出,join()是成員方法
二.線程同步機制初步
1.先了解兩個概念
①異步編程模型:t1線程執行t1的,t2線程執行t2的,兩個線程之間誰也不等誰(一般情況下效率更高)
②同步編程模型:t1線程和t2線程執行,但t1線程必須等t2線程執行結束之后,t1線程才能執行,這就是同步編程模型(也就是接下來要講的)
2.為何要引入線程同步?
為了數據的安全。盡管應用程序的使用效率降低了。
線程同步機制使程序變成了(等同)單線程。
3.什么條件下使用線程同步?
①必須是多線程環境
②多線程環境共享同一個數據
③共享的數據涉及修改操作(比如只涉及查找操作,那就不需要線程同步)
4.錯誤示范
以下程序不使用線程同步機制,多線程同時對同一個賬戶進行取款操作,看看會出現什么問題
public class 測試程序 {
public static void main(String[] args) throws InterruptedException {
//創建一個公共的賬戶
Account act = new Account("actno",5000.0);
//創建兩個線程,這兩個線程對同一個賬戶取款
Thread t1 = new Thread(new Processor(act));
Thread t2 = new Thread(new Processor(act));
//開始取款
t1.start();
t2.start();
}
}
//取款線程
class Processor implements Runnable{
//賬戶
Account act;
//構造方法
Processor(Account act){
this.act = act;
}
public void run() {
act.withdraw(1000);
System.out.println("取款1000元成功,余額為:" + act.getBalance());
}
}
//賬戶
class Account{
private String actno;
private double balance;
//構造方法
public Account(String actno,double balance) {
this.actno = actno;
this.balance = balance;
}
//setter and getter
public void setBalance(double balance) {
this.balance = balance;
}
public double getBalance() {
return balance;
}
//對外提供一個取款的方法
public void withdraw(double money) {
double after = balance - money;
//更新余額
this.setBalance(after);
}
}
輸出結果
取款1000元成功,余額為:4000.0
取款1000元成功,余額為:4000.0
這就已經不對了,取出來2000.0,應該還剩3000.0
所以我們對于類似這種情況,就要使用線程同步了
5.線程同步的語法
synchronized(共享對象){}
{}里面放需要同步的代碼
6.以下程序使用線程同步機制
public class 測試程序 {
public static void main(String[] args) throws InterruptedException {
//創建一個公共的賬戶
Account act = new Account("actno",5000.0);
//創建兩個線程,這兩個線程對同一個賬戶取款
Thread t1 = new Thread(new Processor(act));
Thread t2 = new Thread(new Processor(act));
//開始取款
t1.start();
t2.start();
}
}
//取款線程
class Processor implements Runnable{
//賬戶
Account act;
//構造方法
Processor(Account act){
this.act = act;
}
public void run() {
act.withdraw(1000);
System.out.println("取款1000元成功,余額為:" + act.getBalance());
}
}
//賬戶
class Account{
private String actno;
private double balance;
//構造方法
public Account(String actno,double balance) {
this.actno = actno;
this.balance = balance;
}
//setter and getter
public void setBalance(double balance) {
this.balance = balance;
}
public double getBalance() {
return balance;
}
//對外提供一個取款的方法
public void withdraw(double money) {
synchronized(this) {
double after = balance - money;
//延遲
try{Thread.sleep(1000);}catch(Exception e) {}
//更新余額
this.setBalance(after);
}
}
}
輸出結果
取款1000元成功,余額為:4000.0
取款1000元成功,余額為:3000.0
而且是每1s輸出一行
這樣就是我們需要的,雖然效率降低了,但是安全是最重要的