必必须掌握的线程知识点

java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口

Thread类是在java.lang包中定义的,一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限

详见:http://developer.51cto.com/art/201203/321042.htm

知识点一、实现自定义线程类

  1. 定义实现类实现Runnable接口
  2. 重写run方法
  3. 创建Thread类对象,将Runnable接口的子类对象作为参数传递给Thread类的构造函数
  4. 调用Thread类的start方法开启线程
    // 实现自定义线程类
    public class SubRun implements Runable{
        @Override
        public void run(){
            for( int i=0; i<50; i++){
                System.out.println(Thread.currentThread().getName()):
            }
        }
    }
    // 测试类
    public static void main(String[] args){
        SubRun sr = new SubRun();
        Thread t = new Thread(sr);
        t.start();
    }

     

知识点二、为啥非要使用start()方法启动多线程呢?

一旦调用start()方法,则会通过JVM找到run()方法

在源码中找到Thread中的start()方法,此方法中使用了private native void start0();其中native关键字表示可以调用操作系统的底层函数,那么这样的技术成为JNI技术(java Native Interface)

Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能

Java平台有个用户和本地C代码进行互操作的API称为Java Native Interface (Java本地接口)

使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的

1、为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问

2、为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的

3、为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现

 

知识点三、线程同步

简单来说有:同步代码块 同步方法(还有另外的好多种)

同步是一种高开销的操作,没有必要同步整个方法,同步关键代码即可

同步代码块 :有synchronized关键字修饰的语句块

同步代码块中的锁对象可以是任意的对象;但多个线程时,要使用同一个锁对象才能够保证线程安全。在同步代码块中调用了sleep方法并不是释放锁对象的

synchronized(obj){

//同步代码块

}

同步方法:有synchronized关键字修饰的方法

同步方法中的锁对象固定是this

静态同步方法:在方法声明上加上static synchronized

静态同步方法中的锁对象是类名.class

当synchronized修饰一个static方法时,多线程下获取的是类锁,Calss锁可以对类的所有实例起作用

当synchronized修饰一个非static方法时,多线程下获取的是对象锁(即类的实例对象)

 

知识点四、受阻塞和等待休眠

受阻塞:线程具有执行资格,没有CPU时间

等待和休眠:线程放弃执行资格

sleep和wait区别:

sleep是Thread类的方法 自己睡 到时间自己就醒了 sleep休眠时 不释放锁

wait是Object类方法 等待后 得notify唤醒 wait等待时 释放锁

必必须掌握的线程知识点_第1张图片

 

知识点五、synchronized和Lock

1.synchronized是Java中的关键字,是jdk自带的;Lock是一个接口

2.synchronized在线程执行发生异常时,jvm会让线程释放锁,因此不会导致死锁现象发生;Lock在finally中必须通过unLock()去释放锁,不然容易造成线程死锁

3.使用synchronized时,如果A线程阻塞,B线程会一直等待,不能够响应中断;Lock可以尝试获得锁,线程可以不用一直等待,通过interrupt()方法能够响应中断(interrupt无法中断已经获取的锁,只能中断等待状态)

4.synchronized无法判断锁的状态;Lock可以知道有没有成功获取锁(可以通过其中的tryLock()等自带的多个方法去尝试获取锁)

在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当多线程竞争资源非常激烈时,此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。

 

知识点六、线程中断

1.stop()方法,在一个线程对象上调用stop()方法时,线程占用的锁被强制释放,极易导致数据的不一致性或者带锁无限休眠

2.interupt()方法,使用等待/通知机制或者给那个线程一个中断信号, 让它自己决定该怎么办

中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断

中断是通过调用Thread.interrupt()方法来做的. 这个方法通过修改了被调用线程的中断状态来告知那个线程, 说它被中断了. 对于非阻塞中的线程, 只是改变了中断状态, 即Thread.isInterrupted()将返回true; 对于可取消的阻塞状态中的线程, 比如等待在这些函数上的线程, Thread.sleep(), Object.wait(), Thread.join(), 这个线程收到中断信号后, 会抛出InterruptedException, 同时会把中断状态置回为true.但调用Thread.interrupted()会对中断状态进行复位。

 

 

你可能感兴趣的:(线程)