黑马程序员技术交流社区

标题: 线程的生命周期及状态转换 [打印本页]

作者: 徐方锐    时间: 2016-5-26 13:02
标题: 线程的生命周期及状态转换
线程的生命周期及状态转换:
新建(new),就绪(Runnable),运行(running),阻塞(blocked),死亡(Terminated)

新建:
Thread thread = new Thread();
或者:

Runnable r = new Runnable();
Thread thread = new Thread(r,"新线程");

就绪:
执行run()方法

阻塞:
1)程序试图获取某个对象的同步锁,而该锁被其他线程说持有---获取到其他线程所持有的锁
2)线程调用了一个阻碍式的io方法---io方法返回
3)线程调用了某个对象的wait()方法---notify()方法唤醒
4)线程调用了Thread的sleep(long millis)方法---等
5)一个线程中调用了另一个线程的join()方法---等




线程的调度:为程序中的线程分配cpu的使用权

分为:
分时调度模型
抢占式调度模型(默认)



线程的优先级:1-10
三个Thread的静态常量:
static int MAX_PRIORITY:10
static int MIN_PRIORITY:1
static int NORM_PRIORITY:5


setPriority(int newPriority)来设置优先级


Example07.java:

class MaxPriority implements Runnable {

        public void run(){

                for(int i = 0 ; i < 10 ; i++){

                        System.out.println(i);

                }

        }

}


class MinPriority implements Runnable {

        public void run(){

                for(int i = 0; i <10 ; i ++){

                        System.out.println(i);

                }
        }

}



class Example07 {

        public void static main(String[] args){

                MaxPriority maxPriority = new MaxPriority();
               
                MinPriority minPriority = new MinPriority();

                Thread t1 = new Thread(maxPriority,"高优先级线程");
                Thread t2 = new Thread(minPriority,"低优先级线程");

                t1.setPriority(MAX_PRIORITY);
                t2.setPriority(MIN_PRIORITY);

                t1.start();
                t2.start();

        }

}


线程让步:Thread.yield();
线程插队:jion();
线程休眠:sleep();

Example10.java---多线程以及线程的插队

public class Example10 {
               
        public void stati main(String[] args){

                EmergencyThread emergencyThread  = new EmergencyThread();
                Thread t = new Thread(emergencyThread , "插线程");
                for(int i = 0 ; i <= 5 ; i ++){
                        System.out.println(Thread.currentThread().getName() + i)
                        if(i == 2 ){

                                t.join();
                        }
                        Thread.sleep(500);
                }
        }


}

class EmergencyThread implements Runnable {

        public void run(){

                for(int i = 0; i < 6 ; i ++) {

                        System.out.println(Thread.currentThread().getName() + i)
                        
                        try{
                        
                                Thread.sleep(500)
               
                        }catch{

                        }

                }

        }
}




        


多线程同步:

保证用于处理共享资源的代码在任何时刻只能有一个线程访问
格式:

synchronized(lock){

        操作共享资源的代码

}

锁对象的创建代码不能放到run()方法中,要放外边,synchronized(lock){}放在run()方法内


Example12.java

class Ticket1 implements Runnable {

        private int tickets = 10;
        Object object = new Object();
        
        public void run(){

                while(true){

                        synchronized(lock){

                                try{
                                        Thread.sleep(500);
                                }catch{}

                                if(tickets > 0){
                                
                                        System.out.println(Thread.currentThread().getName() + "---票号"+tickets--);

                                }else{

                                }

                        }

                }
        }

}

public class Example12{

        public void static main(String[] args){

                Ticket1 t1 = new Ticket();
                Thread thread1 = new Thread(t1 , "线程1");
                Thread thread2 = new Thread(t1 , "线程2");
                Thread thread3 = new Thread(t1 , "线程3");

                thread1.start();
                thread2.start();
                thread3.start();

        }
}



同步方法也可以实现和synchronized(lock){}同样的效果
格式:
synchronized 返回值类型 方法名(参数){}



class Ticket1 implements Runnable {
        int tickets = 10;

        public void run(){

                while(true){

                        saleTickets();
                        
                        if(tickets <= 0){

                                break;
                        
                        }

                }
        }

        private synchrozied  void saleTickets(){

                if(tickets > 0) {

                        System.out.println(Thread.currentThread().getName() + "售出"+ tickets -- "张票");

                }

        }

}

public class Example13 {

        public void main(String[] args){

                Ticket1 t = new Ticket1();
                new Thread(t , "线程1").start();
                new Thread(t , "线程2").start();
                new Thread(t , "线程3").start();

        }
}


同步方法的锁就是当前调用该方法的对象,也就是this指向的对象。
静态同步方法的锁死该方法所在类的class对象


线程的通信:

thread.wait()
thread.notify()
thread.notifyAll()

没有线程之间的通信的情况下,会出现乱入问题



先写一个对象类:
class Storage{
        //用于储存数据的数组
        private int[] arr = new int[10];
        //数组的角标
        private int outIndex, inIndex;

        //存数据
        public void put(int num){

                arr[inIndex] = num;
                System.out.println("在arr["+inIndex+"]中存入数据“+arr[inIndex]);
                inIndex ++;
                if(inIndex > 10){
                        inIndex  = 0
                };
        }

        //取数据
        public void get() {

                int data = arr[outIndex];
                System.out.println("从arr["+outIndex+"]中取出数据"+arr[outIndex]);
                outIndex++;
                if(outIndex == arr.length){
                        outIndex = 0;
                };
        }
}


再来线程类:
class Input implements Runnable {
        Strorage s = new Strorage();
        int num ;
        
        //要写一个构造方法来接受一个storage对象
        Input(Storage s ){
        
                this.s =  s ;
        }
        public void run(){
        
                while(true){
                        
                        s.put(num);
                        
                        num ++;
                }
        }
}

class Get implements Runnable {

        Strorage s  = new Storage();
        //要写一个构造方法来接受一个storage对象!
        Get(Storage s){

                this.s = s;
        }

        public void run(){

                while(true){

                        s.get();

                }
        }
}


现在可以写测试方法了:

public class test{

        public void static main(String[] args){

                Storage st = new Storage();
                Input input  = new Input(st);
                Output output  = new Output(st);
                new Thread(input).start();
                new Thread(output).start();

        }
}

这时会发现各线程比较混乱
解决问题的方法:
1)用count记录数量
2)用wait()和notify()

其实每个方法也只添加了4行代码

class Storage{

//new一个贮存空间
int[] arr = new int[10];
//用来记录数量的count
int count ;
int inIndex,outIndex;

public synchronized void put(int num){
        
        while(count == 10){

                this.wait();
        }

        arr[inIndex] = num;
        inIndex ++;
        if(inIndex == 10){
                inIndex = 0;
        }

        count ++;
        this.notify();

}

public synchronized void get(){

        while(count == 0 ){
                this.wait();
        }
        
        int data = arr[outIndex];
        outIndex++;
        if(outIndex == 10){
               
                outIndex = 0;
        }
        
        count --;
        this.notify();

}




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2