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);
}
}