Java學習 Day 10

daemon

	守護線程(服務員)
	爲其它線程提供服務的線程
	若進程中剩餘的線程都是守護線程的話,則進程終止
	Thread.setDaemon(true);

	例:
	class ThreadDemo1{
public static void main(String[] args){
		Box b1 = new Box("1",2000);
		Box b2 = new Box("2",6000);
		starter w = new starter();
		//設置線程爲守護線程
		w.setDaemon(true);
		b1.start();
		b2.start();
		w.start();

	}
}


class Box extends Thread{
	private String no;
	private int time;
	public Box(String no,int time){
		this.no = no;
		this.time = time;
	}
	public void run(){
		System.out.println(no + "號房間開始消費!");
		try{
			Thread.sleep(time);
			System.out.println(no + "號房間消費結束! 消費時間:" + time);
		}
		catch(Exception e){
		}

	}

}

class starter extends Thread{
	public void run(){
		while(true)
		{
			System.out.println(new java.util.Date());
			try{
				Thread.sleep(1000);
			}
			catch(Exception e){}
		}
	}

}

在這裏插入圖片描述

--(減減)
---------------
	原子性操作

線程間通信,資源共享的問題
	鎖,防止併發訪問,有並行改爲串行
	參照物,鎖旗標

例:
class ThreadDemo1{
	public static void main(String[] args){
		Saler s1 = new Saler("S1");
		Saler s2 = new Saler("S2");
		s1.start();
		s2.start();
	}
}

class Saler extends Thread{
	static Object lock = new Object();   // 這裏的static的意義:若不加static,則在實例化時每次都會有一把新鎖,而我們需要用一把鎖

	public static int tickets = 100;
	private String name;
	public Saler(String name){
		this.name = name;
	}
	public void run(){
		while(true){
			int t = getTicket();
			if(t == -1)
				return;
			else 
				System.out.println(name + ":" + t);			
		}
	}
	public int getTicket(){
		synchronized(lock){
			int t = tickets;
			tickets -=1;
			return t < 1 ? -1:t;
		}
	}

}

在這裏插入圖片描述
//同步代碼塊

synchronized{
		...
	}
同步代碼塊執行期間,線程始終持有對象的監控權,其他線程處於阻塞狀態。

例:

class ThreadDemo2{
	public static void main(String[] args){
		TicketPool t = new TicketPool();
		Saler s1 = new Saler("s1",t);
		Saler s2 = new Saler("s2",t);
		Saler s3 = new Saler("s3",t);
		Saler s4 = new Saler("s4",t);
		s1.start();
		s2.start();
		s3.start();
		s4.start();
	}
}
//售票員
class Saler extends Thread{
	private String name;
	private TicketPool pool;
	public Saler(String name,TicketPool pool){
		this.name = name;
		this.pool = pool;
	}
	public void run(){
		while(true){
			int no = pool.getTicket();
			if(no == 0){
			return ;

			}
			else {
				System.out.println(name + ":" + no);
				Thread.yield();
			}
		}
	}
	
}

//票池
class TicketPool{
	private int tickets = 9;
	public synchronized int getTicket(){
		//同步代碼塊,以票池本身爲鎖旗標
		int temp = tickets;
		tickets = tickets - 1;
		return temp >0 ? temp : 0;
	}
}

在這裏插入圖片描述

//票池1
class TicketPool{
	private int tickets = 9;
	public synchronized int getTicket(){
		int temp = tickets;
		tickets = tickets - 1;
		return temp >0 ? temp : 0;
	}
}


//票池2
class TicketPool{
	private int tickets = 9;
	public  int getTicket(){
		//同步代碼塊,以票池本身爲鎖旗標
		synchronized(this){
			int temp = tickets;
			tickets = tickets - 1;
			return temp >0 ? temp : 0;
		}
		
	}
}
票池1 和 票池2 中synchronized的用法的效果是一樣的,票池2中的this指以票池本身爲鎖旗標,票池1中在方法上加同步,

以方法所在的對象爲鎖旗標。因爲所有售票員都用一個票池,所以兩種寫法是等價的,都能實現同步和互斥。

同步方法是以當前所在對象做鎖旗標
	synchronized(this) === 同步方法

wait
-------------
	讓當前線程進入鎖旗標的等待隊列。釋放CPU的搶佔權和鎖旗標的監控權。
解決死鎖的問題
	notifyAll() 通知所有線程可以搶佔CPU和鎖旗標的監控權
	wait(1000); 等待1s後自動退出等待序列
	
	 例:
	 class ThreadDemo3{
	public static void main(String[] args){
		//使用java中集合類,List是列表。
		Pool pool = new Pool();
		Productor p1 = new Productor("生產者1",pool);
		Productor p2 = new Productor("生產者2",pool);
		Consumer c = new Consumer("消費者",pool);
		p1.start();
		p2.start();
		c.start();
		
	}
}

//生產者
class Productor extends Thread{
	static int i = 0 ;
	private String name;
	private Pool pool;
	public Productor(String name ,Pool pool){
		this.name = name ;
		this.pool = pool ;
	}
	public void run(){
		while(true){
			pool.add(i++);
			try{
				Thread.sleep(100);
			}
			catch(Exception e){
			
			}
			System.out.println("add" + i + " ");
		}
	}
}

//消費者
class Consumer extends Thread{
	private String name;
	private Pool pool;
	public Consumer(String name , Pool pool){
		this.name = name;
		this.pool = pool;
	}
	public void run(){
		while(true){
			int i = pool.remove();
			try{
				Thread.sleep(100);
			}
			catch(Exception e){
				e.printStackTrace();
			}
			System.out.println("remove"+ i);
		}
	}

}

class Pool{
	private java.util.List<Integer>list = new java.util.ArrayList<Integer>();
	//容器最大值
	private int MAX = 10;
	//添加元素
	public void add(int n){
		synchronized(this){
			try{
				while(list.size()>= MAX){
					this.wait();
				}
				list.add(n);
				System.out.println("size:" + list.size());
				this.notify();
			}
			catch(Exception e){
				e.printStackTrace();
			}

		}
	}

	//刪除元素
	public int remove(){
		synchronized(this){
			try{
				while(list.size() == 0){
					this.wait();
				}
				int i = list.remove(0);
				this.notify();
				return i;
			}
			catch(Exception e){
				e.printStackTrace();
			}
			return -1;
		}
	}
}

java.lang.Runnable

接口
有run()方法,即 public void run();
供現有類實現線程功能
使用Runnable對象創建線程
	new Thread(new Runnable).start();

例:
	class ThreadDemo1{
	public static void main(String[] args){
		new Thread(new Dog()).start();
	}
}

class Animal{
	private String name;
	public String getName(){
		return name;
	}
	public void setName(String name){
		this.name = name;
	}
}

class Dog extends Animal implements Runnable{
	public void eat(){
		System.out.println("like bone!");
	}
	public void run(){
		eat();
	}
}

在這裏插入圖片描述

Priority

優先級
例:
class ThreadDemo1{
	public static void main(String[] args){
		MyThread a = new MyThread("a");
		MyThread b = new MyThread("b");
		System.out.println(a.getPriority());
		a.setPriority(10);
		b.setPriority(1);
		System.out.println(a.getPriority());
		System.out.println(b.getPriority());
		
		a.start();
		b.start();

	}
}

class MyThread extends Thread{
	private String name;
	public MyThread(String name){
		this.name = name;
	}
	public void run(){
		System.out.println(name);
	}
}

在這裏插入圖片描述

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