多執行緒(二)
阿新 • • 發佈:2021-01-06
執行緒同步
還是那個經典問題賣票
一。各自單執行緒賣自己的票
public class CellTicket {
public static void main(String[] args) {
Windows w1= new Windows();
Windows w2= new Windows();
Windows w3= new Windows();
w1.start();
w2.start();
w3.start();
}
}
class Windows extends Thread {
private Integer ticket=100;
@Override
public void run() {
while (ticket>0){
System.out.println(Thread.currentThread().getName()+"賣出第"+ticket+"張票");
ticket--;
}
}
}
二。多執行緒操作公共的100張票,實現runnable介面的方式實現多執行緒,在run方法中使用sleep方法,出現售賣負數的票的情況
public class CellTicket {
public static void main(String[] args) {
myRunnables resource= new myRunnables();
Thread w1=new Thread(resource);
Thread w2=new Thread(resource);
Thread w3=new Thread(resource);
w1.start();
w2.start();
w3.start();
}
}
class myRunnables implements Runnable{
private Integer ticket=100;
public void run() {
while (ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"賣出第"+ticket+"張票");
ticket--;
}
}
}
以上兩個問題是我們學習多執行緒中太常見的情況了,說下下面的情況
一)使用繼承Thread的方式怎麼實現售賣同一個資源的票數,方法將共享資源加上上static關鍵字
class Windowss extends Thread{
//加static
private static Integer ticket=100;
public void run() {
while (ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"賣出第"+ticket+"張票");
ticket--;
}
}
}
出現負票是因為,多個執行緒同時拿到了同一張票,這個問題的解決就需要我們用到synchronized(同步)
synchronized關鍵字
synchronized關鍵字修飾程式碼塊或者方法,稱為同步程式碼塊和同步方法
class myRunnables implements Runnable {
private Integer ticket = 100;
Object o=new Object();
public void run() {
while (true) {
synchronized (o) {
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "賣出第" + ticket + "張票");
ticket--;
}
}
}
}
}
解決了賣重票和賣負數的情況
使用synchronized關鍵字修飾程式碼塊需要一個同步鎖:上面程式碼中用到的同步鎖,就是我new的Object物件。
同步鎖需要具有以下特徵才能實現同步效果:
①可以是任意物件,注意任意的都可以
②該同步鎖物件必須是唯一的,多個執行緒必須使用同一個同步鎖物件。當由程序執行方法時,獲取同步鎖,只有取得鎖才能執行邏輯。沒有取得就要等待。