【Java高级】4.多线程编程

进程:计算机执行的程序实体

线程:一个程序内部的顺序控制流

进程与线程的关系:一个进程可以包含一个或多个线程

           一个线程就是一个程序内部的一个执行线索

      区别:每个进程都有独立的代码和数据空间,进程间切换开销很大

          同一类线程共享代码和数据空间,每个线程都有独立运行的栈和程序计数器,线程切换开销小

多进程:在操作系统中能同时运行多个程序(任务)

多线程:在同一应用程序中有多个顺序流同时执行

多线程实现方式:创建线程类:继承Thread类、实现Runnable接口

          通过Thread类构造器来创建线程对象:Thread()、Thread(Runnable target)

          通过start()方法来激活线程对象

run()方法:线程执行体,代码要在线程上执行,该代码应该写在一个线程类的run()函数中

     写一个类implement Runnable接口,必须覆盖Runnable接口中的run()方法

public class ThreadDemo extends Thread{
        public void run(){线程体}  
}
public class TestThread{
         public Static void main(String[] args){
                 ThreadDemo t=new ThreadDemo();
                 t.start();
}         

       写一个类extends Thread类,必须重写Thread类中的run()方法

public class RunnableDemo implements Runnable{
    public void run(){线程体}
}
public class TestRunnable{
         public Static void main(String[] args){
                RunnableDemo runner=new RunnableDemo();
                Thread t=new Thread(runner);
                t.start();
}

两种实现方式的比较

    使用Runnable接口可以避免由于Java的单继承性带来的局限,如线程类需要继承某个类,而一个类不能有两个父类

            适合多个相同的程序代码的线程去处理同一资源情况

            把程序的代码、数据有效的分离  

线程状态:创建:线程刚被创建

      就绪状态:start()方法使线程处于就绪状态,但不一定立即开始运行

      运行状态:就绪状态的线程通过CPU调度进入运行状态

      阻塞状态:运行状态的线程由于阻塞时间进入阻塞状态,阻塞解除后进入就绪状态

      终止:线程运行结束

线程类方法

线程优先级:Java提供一个线程调度器来监控程序中启动后进入就绪状态的所用线程

      线程调度器按照线程优先级来决定应调度哪个线程来执行

      Priority,用数字表示,从1到10,缺省的优先级为5

线程休眠:sleep()让线程睡眠一段时间,到时间后线程进入就绪状态

      join()调用其他线程,当其他线程结束后,再恢复该线程运行

      yield()主动让出CPU,当前线程进入就绪队列等待调度

线程终止:自动终止:线程执行完毕,不能再运行

      手动终止:stop()线程马上终止,不安全,已过时,基本不用

            interrupt()让阻塞状态的线程提前出来,不能停止正在运行的线程,不推荐

            通过使用一个标志指示run方法退出,从而终止线程

线程的高级操作:wait()导致当前线程等待,知道其他线程调用此对象的notify方法或notifyAll()方法

          notify()唤醒在此对象监视器上等待的单个线程,由Java虚拟机决定唤醒哪一个

          notifyAll()唤醒在此对象监视器上等待的全部线程

线程同步:为了确保在任意时间点一个共享资源只能被一个线程使用,使用了线程同步

实现同步的两种方式:锁定方法:synchronized void methodA(){}

            锁定代码块:synchronized(Object){}

    优缺点:锁定方法可以显示的知道哪些方法被锁定

            方法中有些程序不需要被保护,会影响效率

            只能取得自己对象的锁

        锁定代码块可以针对某段代码进行锁定,效率高

             可以取得不同对象的锁

             无法显示的知道哪些方法是被锁定的

    注意:受到synchronized保护的程序代码块和方法,要访问的对象属性必须设为private,否则达不到保护的目的

一旦一个包含锁定方法(用synchronized修饰)的线程被CPU调用,其内部其他线程就无法调用相同对象的锁定方法

当一个线程在锁定方法的内部,所有试图调用该方法的同实例的其他线程必须等待

死锁:乱用synchronized可能会造成系统死锁的状态

    两个线程互相等待对方已获取的资源,导致都无法继续运行

锁的归还:执行完锁定的代码后,锁就会自动归还

      用break语句跳出锁定的语句块,但对锁定方法的synchronized没有作用

      遇到return语句

      遇到异常

 

posted @ 2017-10-21 11:36  chain155  阅读(76)  评论(0)    收藏  举报