/*
join
如果 A 執行緒正在運行,流程中允許 B 執行緒加入,等到 B 執行緒執行完畢再繼續 A 執行緒流程就可以使用 join() 方法完成需求,當執行緒使用 join() 加入至另一執行緒時,另一執行緒會等待被加入的執行緒工作完畢然後再續繼它的動作。
*/
//*****************************************************************************
// joinDemo.java
public class joinDemo{
 public static void main(String args[]){
  System.out.println("Main thread 開始…");
  Thread threadB = new Thread(){
   public void run(){
    try{
     System.out.println("Thread B 開始…");
     for(int i=0;i<5;i++){
      Thread.sleep(1000);
      System.out.println("Thread S 執行…");
     }
     System.out.println("Thread B 結束");
    }catch(InterruptedException e){
     e.printStackTrace();
    }
   }
  };
  threadB.start();
  try{
   //Thread B 加入 Main Thread 流程
   threadB.join();
  }catch(InterruptedException ex){
   ex.printStackTrace();
  }
  System.out.println("Main Thread 將結束…");
 }
}
//*****************************************************************************
/*
Thread Group
每個執行緒都屬於某個執行緒群組,可以使用以下程式片段取得目前執行緒所屬的執行緒群組。
Thread.currentThread().getThreadGroup().getName();
可以自行指定執行緒群組,執行緒一旦加入,即無法更改群組。
java.lang.ThreadGroup 可以管理群組中的執行緒。
*/
//*****************************************************************************
package java_0920;
public class ThreadGroupDemo {
 public static void main(String args[]){
  ThreadGroup tg1 = new ThreadGroup("tg1");
  
  Thread t1 = new Thread(tg1, new Runnable(){
   public void run(){
    throw new RuntimeException("t1 測試例外");
   }
  },"tg1");
  
  t1.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
      
   public void uncaughtException(Thread t, Throwable e) {
    System.out.printf("%s ... %s%n", t.getName(), e.getMessage());
   }
  });
  
  Thread t2 = new Thread(tg1, new Runnable(){
   public void run(){
    throw new RuntimeException("t2 測試例外");
   }
  },"tg2");
  
  t1.start();
  t2.start();
 }
}
//*****************************************************************************
// 兩執行緒同時間點別相同的方法,會出現競速狀態出現 Error
// 下例的 Error: Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException
// java.lang.OutOfMemoryError 先不管它,此處為了探討競速物件。
import java.util.Arrays;
public class ArrayList {
 private Object[] list;
 private int next;
 public ArrayList(int capacity){
  list = new Object[capacity];
 }
 public ArrayList(){
  this(16);
 }
 public void add(Object o){
  //System.out.println("add start...");
  if(next == list.length){
   list = Arrays.copyOf(list, list.length * 2);
  }
  list[next++]=o;
 }
 public Object get(int index){
  return list[index];
 }
 public int size(){
  return next;
 }
 public static void main(String args[]){
  ArrayList list = new ArrayList();  
  Thread t1 = new Thread(){
   public void run(){
    while(true){  
      list.add(1);
    }
   }
  };  
  Thread t2 = new Thread(){
   public void run(){
    while(true){    
      list.add(2);
    }
   }
  };  
   t1.start();
   t2.start();   
 } 
}
//-----------------------------------------------------------------------------------------------
// 同上範例,加入 synchronized 除掉競速問題
// 同樣會有  java.lang.OutOfMemoryError 此處不管它
import java.util.Arrays;
public class ArrayList {
 private Object[] list;
 private int next;
 public ArrayList(int capacity){
  list = new Object[capacity];
 }
 public ArrayList(){
  this(16);
 }
 synchronized public void add(Object o){
  if(next == list.length){
   list = Arrays.copyOf(list, list.length * 2);
  }
  list[next++]=o;
 }
 public Object get(int index){
  return list[index];
 }
 public int size(){
  return next;
 }
 public static void main(String args[]){
  ArrayList list = new ArrayList();
  
  Thread t1 = new Thread(){
   public void run(){
    while(true){  
     synchronized(list){      
      list.add(1);
      System.out.println(list.get(list.size()-1));
     }
    }
   }
  };  
  Thread t2 = new Thread(){
   public void run(){
    while(true){    
     synchronized(list){
      System.out.println(list.get(list.size()-1));
      list.add(2);
     }
    }
   }
  };  
   t1.start();
   t2.start();   
 } 
}
//*****************************************************************************
/*
synchronized 與 volatile
在 Java 中對資可見性的要求,可以使用 volatile 達到,在變數上宣告,表示變數是不穩定的是易變的,也就是可能在多執行緒下存取,可保證變數的可見性,也是是若執行緒變動了變數值,另一執行緒一可以看到變更。
不允許執行緒快取,變數的存取是在共享記憶體中進行。
*/
//*****************************************************************************
// 寫一個練習,分為四個檔案:
// Producer.java
package java_0920;
public class Producer implements Runnable {
 private Clerk clerk;
 public Producer(Clerk clerk){
  this.clerk = clerk;
 }
 public void run(){
  System.out.println("生產者開始生產…");
  for(int product=1;product<=10;product++){
   try{
    Thread.sleep((int)(Math.random()*3000));
   }catch(InterruptedException ex){
    throw new RuntimeException(ex);
   }
   clerk.setProduct(product);
  }
 }
}
//Consumer.java
package java_0920;
public class Consumer implements Runnable {
 private Clerk clerk;
 public Consumer(Clerk clerk){
  this.clerk = clerk;
 }
 public void run(){
  System.out.println("消費者開始消費…");
  for(int i=1;i<=10;i++){
   try{
    Thread.sleep((int)(Math.random()*3000));
   }catch(InterruptedException ex){
    throw new RuntimeException(ex);
   }
   int product = clerk.getProduct();
  }
 }
}
//Clerk.java
package java_0920;
public class Clerk {
 private int product = -1 ;
  
 public synchronized int getProduct() {
  while(this.product != -1){
   try{
    wait();
   }catch(InterruptedException e){
    throw new RuntimeException(e);
   }
  } 
  int p = this.product;
  System.out.printf("消費者取得…(%d)%n",this.product);
  this.product=-1;
  notify();
  return p;
 }
 public synchronized void setProduct(int product) {
  while(this.product != -1){
   try{
    wait();
   }catch(InterruptedException e){
    throw new RuntimeException(e);
   }
  }  
  this.product = product;
  System.out.printf("生產者設定…(%d)%n", this.product);
  notify();
 }
}
//ProducerConsumerDemo.java
package java_0920;
public class ProducerConsumerDemo {
 public static void main(String args[]){
  Clerk clerk = new Clerk();
  new Thread(new Producer(clerk)).start();
  new Thread(new Consumer(clerk)).start();
 }
}
//*****************************************************************************
/*
Collection 集合架構介面關係圖
※可動態產生集合元素
可置入不同型別的資料,依照各集合的特性有:排序性、順序性、不允許重複、是否有鍵值的使用。
<String, Integer> 泛型
public interface Set implements Collection
其特性是無順序性,並且元素與元素之間不得重複。
其利用 equal() 方法來判斷加入的物件是否重複,Set 是資料具唯一性但無順序性的集。
※ 不是用 equals (用於比較字串)
*/
//*****************************************************************************
//HashSet
//沒有順序性 (擺放位置是根據 hashCode) 不允許重複
import java.util.*;
public class HashSetDemo {
 public static void main(String argsp[]){
  HashSet<String> s = new HashSet<String>();
  s.add("SCJP");
  s.add("SCWCD");
  s.add("SCBCD");
  
  Iterator i = s.iterator();
  while(i.hasNext()){
   String str = (String)i.next();
   System.out.println(str + " ");
  }
 }
}
//*****************************************************************************
//練習:重複輸入的資料只顯示一個
import java.util.*;
public class HashSetDemo2 {
 public static void main(String args[]){
  Set<String> words = new HashSet<String>();
  Scanner scanner = new Scanner(System.in);
  System.out.println("Input english word:");
  String line = scanner.nextLine();
  String tokens[] = line.split(" ");
  for(String token:tokens){
   words.add(token);
  }
  
  System.out.printf("不重複的單字有(%d)個 %s%n", words.size(), words);
  
 }
}
//執行後自己手動輸入單字,以空白隔開,會自動過濾並顯示出不重複單字。
//*****************************************************************************
import java.util.*;
class Student {
 private String name;
 private String number;
 Student(String name, String number){
  this.name=name;
  this.number=number;
 }
 public String toString(){
  return String.format("(%s %s)", name, number);
 }
}
public class StudentDemo{
 public static void main(String args[]){
  /*
  Set<String> set = new HashSet<String>();
  set.add(new Student("Justin", "B6789").toString());
  set.add(new Student("Monica", "B8765").toString());
  set.add(new Student("Joe", "B213678").toString());
  */
  Set set = new HashSet();
  set.add(new Student("Monica", "B8765"));
  set.add(new Student("Justin", "B6789"));
  set.add(new Student("Joe", "B213678"));
  
  
  System.out.println(set);  
 }
}
沒有留言:
張貼留言