多线程

程序是为完成特定的任务、用某种语言编写的一组指令的集合,即指一段静态的代码,静态对象。

进程是程序的一次动态执行,或者是正在运行的一个程序。动态过程,有它自身的产生、存在、消亡

线程:是一个程序内部的一条执行路径,若一个程序执行过程中,在同一时间可以执行多个线程,就是支持多线程的

每个程序中都隐含一个主线程、main()方法

 

何时需要多线程:

程序需要同时执行两个或者多个任务

程序需要实现一些等待的任务,如:用户输入、文件的读写操作、网络操作、搜索

需要一些后台运行程序时候

 

线程的创建和启动

public class Sample {
    public void method1(String str){
        System.out.println(str);
    }
    public void method2(String str){
        method1(str);
    }
    public static void main(String[] args) {
        Sample  s = new Sample();
        s.method2("hello!");
    }
}

 

多线程的创建和启动

 java语言的jvm运行创建多个线程,它通过java.lang.Thread类来实现

 

Thread类的特性:

每个线程都是通过某个特定的Thread对象的run方法来完成操作的,经常把run方法的主体称为线程体,通过该Thread对象的start方法调用这个线程

 

 

 构造方法:

Thread():创建新的Thread对象

Thread(String name)创建线程并指定实例名称

Thread(Runnable target):指定创建线程的目标对象,它实现了Runnable接口中的run方法

Thread(Runnable target, String name)创建新的Thread对象

 

创建线程的两种方式:

1、继承Thread类,重写类中的run方法,创建线程对象,调用start方法,启动线程

2、实现Runnable接口:重写接口中的run方法,通过带参构造创建对象,调用start方法,开启线程

 

继承方式和实现方式的区别和联系:

public class Thread extends Object implements Runnable{}

 

实现方法的好处:

1、避免了单继承的局限性

2、多个线程可以共享一个接口实现类的对象,非常合适多个相同线程线程来处理同一份资源

 

线程的调度:

 

 线程的优先级:

线程的优先级控制

 

 线程创建时候继承父线程的优先级

 Thread类的有关方法:

线程让步:暂停当前正在执行的线程,把执行机会让给优先级更高或者相同的其它线程,若对列中没有优先级相同的线程,忽略此方法

 

当某个程序调用其他线程的join方法时候,调用线程将被阻塞,知道join方法线程执行完成(第优先级的方法也可以先执行)

 

使用多线程的优点:

只使用单个线程完成多个任务(调用多个方法),肯定比用多个线程来完成时间更短

多线程的优点:

1、提高应用程序的相应,对图形化界面更有意义,可以增强用户体验

2、提高计算机系统的cpu利用效率

3、改善程序结构,将既长又复杂的进程分为多个线程,独立运行,利于理解和修改

 

线程的分类:一种是守护线程、一种是用户线程(唯一的区别是jvm何时离开),守护线程是用来服务用户线程的,通过在start方法前调用thread.setDeamon(true)可以把一个用户线程变成一个守护线程

 

java垃圾回收就是一个典型的守护线程

若jvm都是守护线程,当前jvm将退出

 

线程的声明周期:jdk中用Tread.State枚举表示了线程的集中声明周期

要想实现多线程,必须在主线程中创建新的线程对象

新建:

就绪:新建的e线程经过start方法后,就进入了线程队列进行等待cpu时间片,此时已经具有了运行的条件

运行:就绪的线程被调度并获得处理器的资源时候,便进入运行状态,run方法中定义了线程的操作和功能

阻塞:在某些特殊情况下,被认为挂起或者执行输入输出操作的时候,让出cpu并临时终止自己的执行,进入阻塞状态

死亡:线程完成它的所有工作,或者被强制性的终止

 

 

线程同步:

多个线程执行的不确定性引起执行结果的不稳定性

多个线程对共享,会造成操作的不完整性,会破坏数据

 

 

 

synchronized的使用方式:

 

synchronized(对象){需要同步的代码}

 

synchronized可以放在方法声明中,表示整个方法为同步方法

public synchronized  void show(String name){} 

 

 

 互斥锁:(保证共享数据的操作的完整性)

每个对象都对应一个可称为“互斥锁”的标记,这个标记用来保证在任意时刻,只有一个线程访问该对象

 

同步的局限性:导致程序的执行效率变低

同步方法(非静态)的锁为this

同步方法(静态)的锁为当前类本身

 

 释放锁的e操作:

当前线程的同步方法、同步代码块执行结束

当前线程在同步代码块中、同步方法中遇到了break、return终止了该代码块的执行

当前线程在同步代码块中、同步方法出现了异常

当前线程在同步代码块中执行了对象的wait方法,当前线程暂停、并释放了锁

 

不会释放锁的操作:

在执行同步代码块中,程序调用Thread.sleep()   Thread.yield()方法暂停当前线程的执行

线程执行同步代码块中,其他线程调用了该线程的suspend()方法将该线程挂起

应该尽量避免使用suspend()和resume()来控制线程

 

线程的死锁问题:

不同的线程都在分别占用对方需要的资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁

解决办法:

专门的算法、原则

尽量减少同步资源的定义

 

线程通信:

wait()   notify()  notifyAll()

wait:令当前线程挂起并放弃cpu、同步资源、是别的线程可以访问并修改共享资源,而当前线程排队等待再次对资源的访问

notify:唤醒正在等待的线程(优先级最高者)

notifyAll:唤醒正在排队等待资源的所有线程结束等待

java.lang.Object提供的这三个方法只有在synchronized方法或代码块中 才能使用

 

 

 

 

 

 

 

 

 

 

posted @ 2018-04-27 22:46  coderlzb  阅读(137)  评论(0编辑  收藏  举报