線程組:(ThreadGroup)
把多個線程組合到一起,可以對一批線程進行分類管理,java允許程序直接對線程組進行控制。
默認情況下線程屬於main的線程組,通過getThreadGroup().getName()方法可知。main線程也是屬於名爲main的線程組。
創建自己的線程組:
ThreadGroup tg = new ThreadGroup("我的線程組");
Thread t = new Thread(tg, myThread);
可以通過組名來設置同一個組的線程
例如:tg.SetDaemon(true);將組裏所有線程設爲守護線程
線程池:
當創建線程的時間和銷燬線程的時間大於線程執行的時間時使用線程池。
爲了節省時間和內容,將創建線程的時間在執行之前就全部完成。並且線程的數量固定,這樣可以重用空閒線程。
線程池裏的每一個線程代碼結束後,並不會死亡,而是再次回到線程池中成爲空閒狀態,等待下一個對象來使用。
Executors
JDK5新增了一個Executors工廠類來產生線程池,有如下幾個方法
public static ExecutorService newCachedThreadPool()
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newSingleThreadExecutor()
這些方法的返回值是ExecutorService對象,該對象表示一個線程池,可以執行Runnable對象或者Callable對象代表的線程。它提供瞭如下方法
Future<> submit(Runnable task):執行線程任務
void shutdown() 關閉任務
public class TestExecutors {
public static void main(String[] args) {
//創建一個線程池
ExecutorService executor = Executors.newSingleThreadExecutor();
//2:將線程丟到線程池中。
executor.execute(new MyRunnable());
executor.execute(new MyRunnable());
executor.execute(new MyRunnable());
//關閉線程池
executor.shutdown();
/*ArrayBlockingQueue array = null;
array.add(e)*/
}
}
class MyRunnable extends Thread{
@Override
public void run() {
//輸出一個語句。
System.out.println(Thread.currentThread().getName()+"執行了");
}
}
使用匿名內部類方法實現多線程:
//繼承Thread類來實現
new Thread(){
public void run() {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+"---"+i);
}
};
}.start();
//實現Runnable接口實現
new Thread(new Runnable(){
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+"---"+i);
}
}
}){}.start();
new Thread(new Runnable(){
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println("hello---"+i);
}
}
}){
public void run() {
for(int i=0;i<100;i++){
System.out.println("word---"+i);
}
}
}.start();
Lock類使用
可以用來替換synchronize,jdk5.0後出現
使用方法:
void lock()
獲取鎖
Condition newCondition()
返回綁定到此 Lock 實例的新 Condition 實例,該方法獲取的Condition有await()等待,signal()喚醒等方法
void unlock()
釋放鎖
/*
* 包子,
* 籃子:6個包子。
* Lock類
* 線程的的總時間=線程的創建時間+線程的執行時間+線程的銷燬時間。
* 5000個線程。
* 創建時間+銷燬的時間》執行時間。
*
*/
public class HomeWork2 {
public static void main(String[] args) {
MyProduce2 pro1 = new MyProduce2();
pro1.setName("生產者1");
MyProduce2 pro2 = new MyProduce2();
pro2.setName("生產者2");
MyCustomer cus1 = new MyCustomer();
cus1.setName("消費者1");
MyCustomer cus2 = new MyCustomer();
cus2.setName("消費者2");
pro1.start();
pro2.start();
cus1.start();
cus2.start();
}
}
class Basket {
// 定義一個變量,
public static int index = 0;// 表示包子的編號。
public static final Lock lock = new ReentrantLock();
// 創建一個監視消費者的Condition
public static final Condition condi_pro = lock.newCondition();
public static final Condition condi_cus = lock.newCondition();
// 容器
public static final int SUM = 6;
// 集合用來裝包子
public static List<MyBaozi> list = new ArrayList<MyBaozi>();
}
class MyBaozi {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public MyBaozi(int id) {
super();
this.id = id;
}
public MyBaozi() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "MyBaozi [id=" + id + "]";
}
}
class MyProduce2 extends Thread {
public void run() {
// 不斷的生產包子。
while (true) {
// 先判斷是否滿了。滿了就等待
// 獲得鎖
Basket.lock.lock();
while (Basket.list.size() >= Basket.SUM) {
// 等待
try {
Basket.condi_pro.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 否則就生產。
// 1;創建一個包子。
Basket.index++;
MyBaozi baozi = new MyBaozi(Basket.index);
// 2:將包子放到籃子裏
Basket.list.add(baozi);
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "生產了"
+ baozi.getId() + "號包子,現有" + Basket.list.size() + "個");
// 喚醒等待中的線程。
Basket.condi_cus.signal();
Basket.lock.unlock();
}
}
}
class MyCustomer extends Thread {
@Override
public void run() {
while (true) {
Basket.lock.lock();
// 先要判斷
while (Basket.list.size() == 0) {
try {
Basket.condi_cus.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 消費。從集合中取出一個包子。
MyBaozi baozi = Basket.list.remove(0);
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "消費了"
+ baozi.getId() + "號包子,現有" + Basket.list.size() + "個");
Basket.condi_pro.signal();
Basket.lock.unlock();
}
}
}