Java高級教程02


1.Java線程

1.1. 多線程和多進程

  • 多進程:操作系統能夠同時進行多個任務: 每個app(word,播放器,瀏覽器)可以同時運行
  • 多線程:同一應用程序中喲多個順序流同時執行
  • 線程是進程中的一部分

1.2. 線程的執行過程:

主要過程:

多線程執行的搶CPU是不規律的,由虛擬機分配

1.3. 創建線程的方法

(1). 方法1:通過run()

  • 定義一個線程類,它繼承類Thread並重寫其中的run()方法,方法run()成為線程體
  • 由於Java只支持單繼承,用這種方法定義的類不能繼承其他類
class ThreadOne extends Thread{
  public void run(){
    for (int i=0; i<100;i++){
      System.out.println("thread one--->" + i);
    }
  }
}

class ThreadTwo extends Thread{
  public void run(){
    for (int i=0; i<100;i++){
      System.out.println("thread two--->" + i);
    }
  }
}

class Test{
  public static void main(String[] args){
    // 生成線程類的對象
    ThreadOne fo = new ThreadOne();
    ThreadTwo ft = new ThreadTwo();
    // 啟動線程---> 進入Runnable狀態---->准備搶CPU
    fo.start();
    ft.start();
  }
}

(2). 方法2: 復寫Runnable接口(推薦)

  • 提供一個實現接口Runnable的類作為線程的目標對象,在初始化一個Thread類或者Thread子類的線程對象時,把目標對象傳遞給這個線程實體,由該目標對象提供線程體
class RunnableImpl implements Runnable{
  public void run(){
    for (int i=0; i<100;i++){
      System.out.println("thread two--->" + i);
    }
  }
}

class Test{
  public static void main(String[] args){
    //生成一個Runnable接口實現類的對象
    RunnableImpl ri = new RunnableImpl();
    //生成一個Thread對象,並將Runnable接口實現類的對象作為參數傳遞給該Thread對象
    Thread t = new Thread(ri);
    // 通知thread執行
    t.start();
  }
}

1.4. 線程的簡單控制

  • 中斷線程
    • Thread.sleep():先睡眠,然后繼續進入就緒狀態,准備搶CPU----記得拋出異常哦,親
    • Thread.yield():讓出CPU,然后繼續進入就緒狀態,准備搶CPU
  • 設置線程的優先級:
    • getPriority(): 獲取優先級
    • setPriority(): 設置優先級(1-10)

2. Java線程同步synchronized

2.1. 多線程數據安全以及synchronized的使用

  • 多線程共用同一份數據的時候,會出問題
class MyThread implements Runnable{
  int i = 100;
  public void run(){
    while (true){
      // 使用synchronized構造同步代碼塊---this為同步鎖
      synchronized(this){
        // Thread.currentThread()獲取當前代碼正在哪個線程中運行
        System.out.println(Thread.currentThread().getName() + i);
        i = i -1;
        Thread.yield();
        if(i<0){
          break;
        }  
      }
    }
  }
}

class Test{
  public static void main(String[] args){
    MyThread myThread = new MyThread();
    // 生成兩個
    Thread t1 = new Thread(myThread);
    Thread t2 = new Thread(myThread);

    t1.setName("thread a");
    t2.setName("thread b");
    // t1先獲得鎖,運行,t2等待
    // t2然后獲得鎖,運行,t1等待
    t1.start();
    t2.start();
  }
}

2.2. 深入synchronized關鍵字

  • 同步鎖不是鎖的代碼塊,鎖的是this, 只要一個對象獲得同步鎖,這個對象其他也含有同步鎖的代碼都不能執行,只能釋放后才能執行
  • 沒有同步鎖的代碼塊跟同步鎖無關,會繼續執行,沒有影響
class Service {
  public void fun1(){
    synchronized(this){
      try{
        Thread.sleep(3*1000)
      }
      catch(Exception e){
        System.out.println(e)
      }
      System.out.println("fun1")
    }
  }
  public void fun2(){
    synchronized(this){
      System.out.println("fun2")
    }
  }
}

class MyThread1 implments Runnable{
  private Service service;

  public MyThread1(Service serivce){
    this.serivce = serivce;
  }
  public void run(){
    service.fun1();
  }
}

class MyThread2 implments Runnable{
  private Service service;

  public MyThread2(Service serivce){
    this.serivce = serivce;
  }
  public void run(){
    service.fun2();
  }
}

class Test{
  public static void main(String[] args){
    Service service = new Service();

    Thread t1 = new Thread(new MyThread1(service));
    Thread t2 = new Thread(new MyThread2(service));
  }
}

2.3. 同步方法

  • 同步方法鎖住的是this
class Service {
  // 同步方法只需要在方法名前加入synchronized即可
  public synchronized void fun1(){
    
      try{
        Thread.sleep(3*1000)
      }
      catch(Exception e){
        System.out.println(e)
      }
      System.out.println("fun1")
    
  }
  public void fun2(){
    synchronized(this){
      System.out.println("fun2")
    }
  }
}

3. Java的數組和類集框架

  • 用於儲存一些列相同數據類型的容器

3.1. 數組類型

  • 數組長度一旦聲明,不可更改
class Test{
  public static void main(String[] args){
    // 一維數組的靜態聲明法
    int[] arr = {1,2,5,7,8,10};
    arr[3] = 10; // 設置數組元素為新的值
    // 打印一維數組元素
    for (int  i=0; i<arr.length; i++){
      System.out.println(arr[i]);
    }
    // 一維數組的動態聲明法  
    int[] arr = new int[10];  // 初始化為0
    // 二位數組的靜態聲明法
    int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
    arr[1][1];  // = 5
    // 二位數組的動態聲明法
    int[][] arr = new int[3][5];
    
    // 打印二位數組
    for (int i=0; i<arr.length;i++){
      for (int j=0; i<arr[i].length; i++){
        System.out.println(arr[i][j]);
      }
    }
  }
}

3.2. Java的類集框架

1. 類集框架的定義和種類,以及基礎結構

  • 類集框架是一組類和結構,位於java.util包中,主要用於儲存和管理對象,主要分為三大類:
    • 集合(Set): 對象不按照特定的方式排序,並且沒有重復對象
    • 列表(List): 對象按照索引位置排序,可以有重復對象
    • 映射(dictionary): 通過鍵-值對儲存(key-value)

類集框架的主體結構

2. ArrayList列表的使用

import java.util.List;
import java.util.ArrayList;


public class Test{
  public static void main(String[] args){
    // arraylist的長度可以自動擴展,跟數組有區別
    // 聲明arraylist只能存String類型
    ArrayList<String> arraylist = new ArrayList<String>();
    // 向arraylist數組添加對象
    arraylist.add("a");
    arraylist.add("b");
    // 從arraylist取對象
    String s = arraylist.get(1);
    // 打印arraylist數據
    for(int i=0; i<arraylist.size(); i++){
      String s = arraylist.get(1);
      System.out.println(s);
    }
    // 刪除arraylist數據 
    arraylist(1);
  }
}

3. Collection和Iterator接口

  • Iterator最高層---hasNext() + Next()
  • Collection接口是Iteator的子接口
  • Set是Collection接口的子接口
  • HashSet是Set的實現類
  • Iterator <-- Collection <-- Set <-- HashSet
  • Iterator <-- Collection <-- List <-- ArrayList

(1) Collection接口

方法 含義
boolean add(Object 0) 向集合添加對象
void clear() 刪除集合的所有對象
boolean isEmpty() 判斷集合是否為空
remove(Object o) 從集合中刪除一個對象的引用
int size() 返回集合中元素的數組

4.Set和HashSet用法(Collection的實現類)

import java.util.Set;
import java.util.HashSet;

public class Test{
  public static void main(String[] args){
    HashSet<String> hashset = new HashSet<String>();
    Set<String> set = hashset;

    boolean b1 = set.isEmpty();  
    
    set.add("a");
    set.add("b");
    set.add("c");
    set.add("a"); // 重復元素會忽略

    int a = set.size();
    set.remove(a);
    set.clear();

    // 集合取數據---通過迭代器Iterator
    // 調用Set對象的Iterator方法,會生成一個迭代器對象,該對象用於遍歷整個Set
    Iterator<String> it = set.iterator();

    while(it.hasNext()){
      //取出元素,並將指針向后面挪一位
      String s = it.next();
      System.out.println(s);
    }

  }
}

5. Map和HashMap的使用方法

  • Map <-- HashMap
import java.util.Map;
import java.util.HashMap;

public class Test{
  public static void main(String[] args){
    // 創建hashmap對象,並定義鍵值對類型
    HashMap<String, String> hasMap = new HashMap<String, String>();
    Map<String, String> map = hasMap;

    map.put("1","a");
    map.put("2","b");
    map.put("3","c");
    map.put("3","e");   // 將會覆蓋上面的鍵值對

    int i = map.size();

    String s = map.get("3");

    
  }
}

4. equals函數的使用方法

4.1. equals的作用

==的作用:

  • 基本數據類型: 是否相等?
  • 引用數據類型: 是否指向堆內存的同一地址?
class User{
  String name;
  int age;
}

class Test{
  public static void main(String[] args){
    User u1 = new User();
    User u2 = new User();
    User u3 = u1;

    boolean b1 = u1 == u2;  // false
    boolean b2 = u1 == u3;  // true
  }
}

eqauls的復寫

  • 兩個對象類型相同(使用instanceof來比較)
  • 兩個對象的成員變量的值完全相同
class User{
  // String是引用數據類型
  String name;
  int age;

  public User(String name, int age){
    this.name = name;
    this.age = age;
  }

  public boolean equals(Object obj){
    if(this == obj){
      return true;
    }
    if(obj instanceof User){
      User u = (User)obj;
      // 這里的equals是Object的
      // equals用於比較內容是否相等
      if (this.age == u.age && this.name.equals(u.name)){
        return true;
      }
      else{
        return false;
      }
    }
    else{
      return false;
    }
  }
  
}

class Test{
  public static void main(String[] args){
    User u1 = new User("zahng",12);
    User u2 = new User("liu",15);
    User u3 = new User("zahng",12);
    
    boolean b1 = u1.equals(u2);  // false
    boolean b2 = u1.equals(u3); // true
  }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM