線程

多線程:

程序運行時:啓動了兩個線程:

Main線程:調用main方法,執行main方法。

GC線程:在main線程運行時運行,回收程序運行之中的垃圾。

線程:一條執行路徑。多線程完成多個功能併發併發執行的效果。

多線程之間亂系執行、同一線程內部順序執行的。

寫多線程:

1. 繼承自Thread類,重寫run方法。然後用Threadstart方法啓動線程。

2. 實現Runnable接口,實現run方法。然後用Threadstart方法啓動線程。

兩種方式的區別:

1. 第一種使用簡單。

2. 第二種不受java單繼承的限制。一般來說,都是用第二種。

線程中常用的方法:線程中的已過時方法禁止使用。其他類中的過時方法不建議使用。

1. start:啓動一個新線程。啓動之後jvm會自動執行run方法。

2. run:線程啓動之後執行的方法。

3. setNamegetName:自動命名,Thread-0,1

4. currentThread:得到當前運行的線程。

5. getPriority()setPriority 得到和設置當前線程的優先級。優先級1-10,如果不指定默認是5. 理論上,誰優先級高,誰被cpu調度的可能性就大。但是優先級低的並不是不執行。資源不足的時候纔有效果。

6. setDaemon:將線程置爲守護線程。只能在線程start之前調用。一般用於爲其他線程提供服務,比如GC。守護線程會隨着其他非守護線程的結束而結束。isDaemon可以用於判斷某個線程是否是守護線程。

7. sleep:讓當前線程停止執行(休眠)一段時間。

8. join:如果在A線程中B線程join進來,則現在執行B的內容,直到B執行完畢才繼續執行A。比如A是顯示數據  B是收集收據。

9. yield:讓位:讓出執行權,和其他線程爭奪資源,誰拿到cpu時間片誰執行。

線程的狀態圖:說明 run方法結束,新線程結束。

package day16;
import java.util.ArrayList;
import java.util.Vector;
public class Bank {
    public static void main(String[] args) {
        // 創建一個賬戶
        Account account = new Account();
        // 你和女朋友操作同一個賬戶
        Person1 you1 = new Person1(account);
        Person1 yourGF1 = new Person1(account);
        Thread thYou1 = new Thread(you1);
        Thread thYourGF1 = new Thread(yourGF1);
        // 你和女朋友同時去取錢。
        thYou1.start();
        thYourGF1.start();
              
        // 存錢線程
        Person2 you2 = new Person2(account);
        Person2 yourGF2 = new Person2(account);
        Thread thYou2 = new Thread(you2);
        Thread thYourGF2 = new Thread(yourGF2);
        thYou2.start();
        thYourGF2.start();
              
              
              
        try {
            Thread.sleep(5000);// 確保賬戶操作完畢
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("最終賬戶餘額:"+account.balance);
    }
}
class Account{
    private ArrayList list;
    private Vector v ;
    public int balance = 2000;
    private Object obj1 = new Object();
//  private Object obj2 = new Object();
    // 取款
    public /*synchronized*/ void withdraw(){// 同一時間只能有一個線程訪問。
        synchronized (obj1) {
            int temp = balance;
            temp = temp - 800;
            try {
                Thread.sleep(1000);// 模擬網絡延遲。
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            balance = temp;
            System.out.println(Thread.currentThread().getName()+"取款");
//          while(true){}
        }
    }
    // 存款
    public /*synchronized*/ void deposit(){// 同一時間只能有一個線程訪問。
        synchronized (obj1) {
            int temp = balance;
            temp = temp + 800;
            try {
                Thread.sleep(1000);// 模擬網絡延遲。
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            balance = temp;
            System.out.println(Thread.currentThread().getName()+"存款");
        }
    }
}
class Person1 implements Runnable{
    // 人要自己的賬戶。
    private Account account ;
    public Person1(Account account){
        this.account = account;
    }
    @Override
    public void run() {
        account.withdraw();
    }
}
class Person2 implements Runnable{
    // 人要自己的賬戶。
    private Account account ;
    public Person2(Account account){
        this.account = account;
    }
    @Override
    public void run() {
        account.deposit();
    }
}

線程相關的常用類:

1. Timer:定時器、調度器、計時器

2. TimerTask:定時任務。

線程間的同步:本質:把異步轉化爲同步,把並行轉爲串行。

方式:

1. 同步語句塊:synchronized(obj){}

2. 同步方法:在方法前加synchronized修飾符,拿到的仍然是本類對象的鎖。

難點:不容易測出來。

對象鎖:每個對象都有一把鎖。同步鎖、互斥鎖

package day16;
import java.awt.BorderLayout;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import com.sun.awt.AWTUtilities;
public class Logo extends JFrame{
    /** logo下標 **/
    private int niIndex = 1;
    /** 顯示圖片內容的標籤 **/
    private JLabel lbShow;
    /** 計時器 **/
    private Timer timer;
    public Logo(){
        JPanel pnBasic = new JPanel();
        pnBasic.setLayout(new BorderLayout());
          
        lbShow = new JLabel();
        pnBasic.add(lbShow,BorderLayout.CENTER);
        lbShow.setIcon(new ImageIcon("fff/role1/1.png"));
          
        setContentPane(pnBasic);
        setTitle("歡迎界面");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(200,200,410,320);
        // 透明
        setUndecorated(true);
        AWTUtilities.setWindowOpaque(this, false);
        setVisible(true);
        // 定義定時器
        timer = new Timer();
        // 1.重複執行的任務 2.延遲多長時間執行 3.執行頻率
        timer.schedule(new LogoMonitor(),1000,500);
    }
      
    private class LogoMonitor extends TimerTask{
        @Override
        public void run() {
            if(niIndex<7){
                niIndex++;
                lbShow.setIcon(new ImageIcon("fff/role1/"+niIndex+".png"));
            }else{
                timer.cancel();
                dispose();
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("進入主界面");
            }
        }
    }
      
    public static void main(String[] args) {
        new Logo();
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章