第二十七节(多线程、线程的创建和启动、生命周期、调度、控制、同步)

 线程指进程中的一个执行场景,也就是执行流程,那么进程和线程的区别是什么
1. 每个进程是一个应用程序,都有独立的内存空间

2. 同一个进程中的线程共享其进程中的内存和资源
(共享的内存是堆内存和方法区内存,栈内存不共享,每个线程有自己的)

什么是进程?

一个进程对应一个应用程序。 例如:在 windows 操作系统启动 Word 就表示启动了一个进程。在 java 的开发环境下启动 JVM,
就表示启动了一个进程。现代的计算机都是支持多进程的,在同一个操作系统中,可以同时启动多个进程。
/*
    分析一下程序有几个线程
        
        只有一个线程,就是主线程
        
        main,m1,m2,m3 这四个方法在同一个栈空间中
        
        没有启动其他任何线程

*/
public class ThreadTest01{
    
    public static void main(String[] args){
        ming01();
    }

    public static void arry01(){
        ming2();    
    }
    
    public static void arry02(){
        ming03();
    }

    public static void arry03(){
        System.out.println("电子科技大学中山学院");
    }

}
/*
    在Java语言中实现多线程第一种方式:
    
        1. 继承java.lang.Thread
        2. 重写run方法

    三个知识点:
        
        定义线程
        创建线程
        启动线程

*/
public class ThreadTest02{

    public static void main(String[] args){
        
        // 创建一个线程
        Thread t = new Student();
        
        // 启动线程
        t.start();
        // start方法执行完瞬间结束,告诉JVM再分配一个新的线程 给t线程
        
        
        // run 不需要手动调用的,系统线程启动之后会自动调用run方法
        // 是随机分配的,没有规律
        
        // t.run(); 这是普通方法的调用,这样做程序只有一个线程,run方法结束之后,下边的程序才能继续运行
        
        for(int i = 0; i < 5; i++){
            System.out.println("main---------: "+i);    
        }
        
        /* 
            有了多线程之后,main方法结束只是主线程中没有方法栈帧了
            但是其他线程或者其他栈中还有栈帧
            main方法结束,程序可能还在运行
        */
        
    }

}

class Student extends Thread{
    
    // 重写run方法
    public void run(){
        for(int i = 0; i < 10; i++){
            System.out.println("run: " + i);    
        }
        
    }

}
/*
    Java中实现多线程的第二种方法:
    
        1. 写一个类实现
        2. 实现run方法

*/
public class ThreadTest03{
    
    public static void main(String[] args){
        
        // 创建线程
        Thread t = new Thread(new Teacher());
        
        // 启动
        t.start();
        
    }
}


// 这种方法是推荐的,因为一个类实现接口之外保留了 类的继承
class Teacher implements Runnable {
    // 重写run方法
    public void run(){
        for(int i = 0; i < 10; i++){
            System.out.println("run: " + i);    
        }
        
    }    
}
/*
    掌握线程方法:
        1. 获取当前线程的对象 currentThread
        2. 给线程起名 t.setName("名称");
        3. 获取线程的名字:t.getName();

*/
public class ThreadTest04{

    public static void main(String[] args){
        
        // 获取当前线程对象 main 主线程
        Thread t = Thread.currentThread();
        // 获取线程的名称
        System.out.println("线程的名称:"+t.getName());//输出main
        
        Thread t1 = new Thread(new MingTest());
        // 给线程起名
        t1.setName("Ming");
        
        t1.start();
        
        
        Thread t2 = new Thread(new MingTest());
        // 给线程重命名
        t2.setName("中山学院");
        
        t2.start();
        
    }


}


class MingTest implements Runnable{
    
    public void run(){
        Thread t =     Thread.currentThread();
        System.out.println("线程名称:"+t.getName());
        
    }
    
}
/*
    线程优先级的高的获取cpu的时间片 相对多一些
    最高:10
    最低:1
    默认:5
    
    优先级:1 - 10
    
    优先级高的线程 会得到CPU的时间多一些,优先执行完成
    
    
*/
public class ThreadTest05{
    
    public static void main(String[] args){
        
        System.out.println("最高:" + Thread.MAX_PRIORITY);
        System.out.println("最小:" + Thread.MIN_PRIORITY);
        System.out.println("默认:" + Thread.NORM_PRIORITY);
        
        Thread t1 = new Keke();
        t1.setName("t1");
        
        Thread t2 = new Keke();
        t2.setName("t2");        
        
        // 都是 5
        System.out.println("t1优先级:" + t1.getPriority());
        System.out.println("t2优先级:" + t2.getPriority());
        
        // 设置优先级
        t1.setPriority(6);
        t2.setPriority(3);
        
        // 启动
        t1.start();
        t2.start();
        
    }

}

class Keke extends Thread{
    
    public void run(){
        for(int i = 0 ; i < 5; i++){
            System.out.println(Thread.currentThread().getName() + "----------- : " + i);    
        }    
    }

}
/*
    Thread.sleep(); 让当前正在执行的线程休眠(暂停执行)
    sleep 方法是一个静态方法
    该方法的作用:阻塞当前线程,腾出CPU,让给其他线程
*/
public class ThreadTest06{
    
    public static void main(String[] args){
        
        Thread t1 = new Ming();
        t1.setName("t1");
        t1.start();
        
        // 获取当前线程对象 main 主线程
        Thread t = Thread.currentThread();
        // 获取线程的名称
        System.out.println("线程的名称:"+t.getName());//输出main
        
        // 阻塞主线程
        for(int i = 0; i < 20; i++){
            System.out.println(Thread.currentThread().getName() + "----------- : " + i);
            try{
                Thread.sleep(1000);
            } catch(InterruptedException e){
                e.printStackTrace();
            }
        }
        
    }
    
}


class Ming extends Thread{
    
    public void run(){
        System.out.println("线程正在启动中.......");
        for(int i = 0; i < 20; i++){
            System.out.println(Thread.currentThread().getName() + "----------- : " + i);
            try{
                Thread.sleep(2000); // 让当前程序阻塞2S
            } catch(InterruptedException e){
                e.printStackTrace();
            }
        }    
    }
    
}

//输出main跟ti是随机的 
/*
    Thread.yield(); 暂停当前正在执行的线程对象,并执行其他线程。 
    
    1. 该方法是一个静态方法
    2. 作用: 给同一个优先级的线程让位,但是让位时间不固定
    3. 和sleep方法相同,就是yield时间不固定
    
    他与sleep类似,只是不能由用户指定暂停多长时间,并且yield()只能让 同优先级的线程有执行的机会
    

*/
public class ThreadTest08{
    
    public static void main(String[] args){
            
        // 创建线程
        Thread t = new Ming5();
        t.setName("t");
        
        // 启动线程
        t.start();
        
        // 主线程
        for(int i = 0; i < 20; i++){
            System.out.println(Thread.currentThread().getName()+"------- "+i);        
        }
        System.out.println("Ming帅了 !");
        
        
    }

}

class Ming5 extends Thread{
    
    public void run(){
        for(int i = 0; i < 10; i++){
            System.out.println(Thread.currentThread().getName()+"------- "+i);    
            if(i % 2 == 0){
                Thread.yield();    
            }
        }    
    }
    
}
/*
    线程的合并

    

*/
public class ThreadTest09{
    
    public static void main(String[] args){
        
        
            Thread t = new Thread(new Arry6());
            t.setName("t");
            t.start();
            
            try{
                // 合并线程
                t.join(); // t 和 主线程合并,单线程的程序
            } catch(InterruptedException e){
                e.printStackTrace();
            }
            
            System.out.println("---------main end--------");
            
            // 主线程
            for(int i = 0; i < 10; i++){
                System.out.println(Thread.currentThread().getName()+"------- "+i);
            }
        
        // 当前线程可以调用第一个线程的join方法,调用后当前线程会被阻塞不再执行,
        // 直到被调用的线程执行完毕,当前线程才会执行
        
        
    }

}

class Arry6 implements Runnable{
    
    public void run(){
        for(int i = 0; i < 10; i++){
            try{
                Thread.sleep(1000);    
                System.out.println(Thread.currentThread().getName()+"------- "+i);    
            }catch(InterruptedException e){
                e.printStackTrace();    
            }
        }    
    }
    
}

 

posted @ 2015-01-19 22:29  哥的笑百度不到  阅读(198)  评论(0编辑  收藏  举报