JAVA温习课堂13

51、线程(Thread)
    (
        程序 program 是对数据描述与操作的代码的集合,是应用程序执行的脚本
        进程 process 程序一次执行过程,系统运行程序的基本单位。程序是静态的,进程是动态的
            系统运行一个程序即是一个进程从创建、运行到消亡的进程。
        多任务 multi task 在一个系统中可以同时运行多个程序,即有多个独立运行的任务,每个任务对应一个进程

        线程 thread 单位比进程 process 更小,程序中单个顺序的流控制,一个进程中可以包含多个线程。
            线程是一个独立的执行流,是进程内部的一个独立执行单元,相当于一个子程序
    )

    实现多线程的两种方式(java程序启动时,jvm自动创建主线程)
        1、(继承Thread 类)创建java.lang.Thread类的子类,重写该类的 run 方法
            重写 run( ) 方法,将业务代码写在方法体中
        2、(实现 Runnable 接口)创建java.lang.Runnabl-e接口的实现类,实现接口中的 run 方法
            定义的线程类已经显示继承了其它类,就不能再继承Thread 类了。
            适合用于资源共享
            Runnable 接口必须实现 run( ) 方法,而Thread 类中的run( ) 方法是一个空方法,可以不重写
            Runnable 接口的实现类并不是真正的线程类,只是线程运行的目标类,要想以线程的方式执行 run 方法必须依靠Thread 类
    启动线程
        1、创建Thread 对象,调用Thread 对象的start( ) 方法,不是调用run( ) 方法
        2、创建Thread 对象,传入参数 Thread(Runnable target),并调用该Thread 对象的start( ) 方法

    资源共享(不考虑线程安全问题)
        实例需求:使用Thread 类,创建两个线程,共同打印0-99
实例代码1:(继承Thread 类)
        public class PrintNumber {

            public static void main(String[] args) {

                int i = 0;
                NumberThread thread1 = new NumberThread("Thread1");
                NumberThread thread2 = new NumberThread("Thread2");

                thread1.setI(i);

                thread1.start();
                thread2.start();
            }
        }

        class NumberThread extends Thread{

            public NumberThread(String threadName) {
                super(threadName);
            }

            @Override
            public void run() {
                for( ;i < 100 ;i++){
                        System.out.println(getName()+" : " + i);
                }
            }

            private static int i;
            public static void setI(int i) {
                NumberThread.i = i;
            }
        }

实例代码2:(实现Runnable 接口)
        public class MyRunnable implements Runnable {

            int i = 0;
            public void run() {
                for(; i<=100 ;i++){
                    System.out.println(Thread.currentThread().getName() + ": " + i);

                }
            }

            public static void main(String[] args) {

                MyRunnable mr = new MyRunnable();

                Thread thread1 = new Thread(mr);
                Thread thread2 = new Thread(mr);

                thread1.start();
                thread2.start();    
            }

    线程的生命周期【状态】(方法:yield( ) 、sleep( ) 、join( )、Interrupt( )、isAlive( ))
        新建:创建一个Thread对象时,该对象就处于 新建状态
        可执行:等待调度,不是马上执行
        执行:处于可执行的状态的线程对象,一旦获得了CPU控制权,就转换为执行状态
               调用 yield( ) 方法,当前线程让出CPU控制权,并重新回到可执行状态,等待调度
        阻塞:线程在执行状态下由于某种条件的影响被迫让出CPU控制权
                调用 sleep( ) 方法,当前线程进入堵塞状态,暂时休眠一段时间,参数单位为毫秒
                调用 join( ) 方法 , 合并某个线程,处在执行状态的线程如果有其他线程调用join( )方法,当前线程将被挂起进入阻塞状态
                   目标线程执行完毕后才会解除阻塞,回到可执行状态
                 执行I/O操作 , 线程在执行过程中访问外部资源而堵塞
                 interrupt( ) 方法:解除处于阻塞状态的线程的阻塞状态, 抛出异常 InterruptedException 
        消亡:处于执行状态的线程一旦从run方法返回,则进入死亡状态,死亡状态的线程不能被重新运行。
                 isAlive( ) 方法,用于判断该线程是否死亡
                 已经结束的线程,不能被重新执行,否则会抛 IllegalThreadStateException
    线程调度
        按照特定机制为线程分配 CPU 时间片段的行为
        Java 程序运行时,由Java 虚拟机负责线程的调度

        线程调度的实现方式
            分时调度模型
                让所有线程轮流获得CPU的控制权,并且为每个线程平均分配CPU时间片段
            抢占式调度模式(Java 虚拟机采用此种调度模型)
                选择优先级相对较高的线程执行,如果所有线程的优先级相同,则随机选择一个线程执行,
    线程优先级(不推荐使用 )
        Thread 类提供设置和获取线程优先级的方法
            getPriority( ) 方法:获取当前线程的优先级
            setPriority( ) 方法:设置当前线程的优先级
            Java语言为线程类设置了10个优先级,分别使用1~10内的整数表示 ,整数值越大代表优先级越高。
            每个线程都有一个默认的优先级,主线程的默认优先级是5
    线程同步
        问题:线程并发,多个线程共享一个资源,出现线程安全问题
        线程安全:多线程应用程序同时访问共享对象时,由于线程间相互抢占CPU的控制权
                   造成一个线程夹在另一个线程的执行过程中运行,所以可能导致错误的执行结果。
        解决线程安全问题(Synchronized 关键字)
            使用synchronized 代码块:需要在synchronized 代码块中参照共同的一个对象,否则不行。

实例代码:(拿苹果)
        public class ShareApple implements Runnable {
            private int appleCount = 5;

            boolean getApple(){             
                synchronized (this) {    // synchronized 代码块 begin
                    if(appleCount > 0 ){
                        appleCount--;
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "拿走一个苹果"+",还剩下" + appleCount + "个苹果");
                        return true;
                    }
                    return false;
                }   // synchronized 代码块 end
            }

            public void run() {
                boolean flag = getApple();
                while(flag){
                    flag = getApple();
                }
                System.out.println(Thread.currentThread().getName() + "线程结束了");
            }

            public static void main(String[] args) {
                ShareApple shareApple = new ShareApple();

                Thread th1 = new Thread(shareApple);
                Thread th2 = new Thread(shareApple);

                th1.setName("EngineerZhong");
                th2.setName("EngineerYe");

                th1.start();
                th2.start();
            }
        }

    线程通信(wait( )、notify( )、notifyall( ))

实例:三个人排队买票,一张票5元,售票处有一张5元
        EngineerZhong  20 元(排队等待其余两位买好后,才够找零)
        EngineerYe 5元
        EngineerZhou 5元

实例代码:
    public class ThreadByeTicket implements Runnable {
        private int fiveCount = 1,tenCount = 0,twentyCount = 0;
        public synchronized void byeTicket(){
            String name = Thread.currentThread().getName();
            // EngineerZhong拥有20元,一张票只需要5元
            if("EngineerZhong".equals(name)){
                if(fiveCount < 3){
                    System.out.println("5元面值的钱有:" + fiveCount + "张   EngineerZhong等待买票~~");
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("5元面值的钱有:" + fiveCount + "张   卖给EngineerZhong一张票,找零15~~");
                }
            }else if("EngineerYe".equals(name)){
                fiveCount++;
                System.out.println("5元面值的钱有:" + fiveCount + "张   卖给EngineerYe一张票,钱正好~~");
            }else if("EngineerZhou".equals(name)){
                fiveCount++;
                System.out.println("5元面值的钱有:" + fiveCount + "张   卖给EngineerZhou一张票,钱正好~~");
            }
            if(fiveCount == 3){
                notifyAll();
            }
        }

        public void run() {
            byeTicket();
        }

        public static void main(String[] args) {
            ThreadByeTicket ticketDemo = new ThreadByeTicket();

            Thread th1 = new Thread(ticketDemo);
            th1.setName("EngineerZhong");
            Thread th2 = new Thread(ticketDemo);
            th2.setName("EngineerYe");
            Thread th3 = new Thread(ticketDemo);
            th3.setName("EngineerZhou");

            th1.start();
            th2.start();
            th3.start();
        }
    }
更新时间:2016年10月7日
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值