您的位置:首页 > 编程语言 > Java开发

Java多线程编程核心技术笔记

2016-07-05 16:30 211 查看
在Java中有以下三种方法可以终止正在运行的线程:

使用退出标志,使线程正常退出,也就是当run方法完成后线程终止

使用stop方法强行终止线程,但不推荐使用这种方法,因为stop和suspend及resume一样,都是作废过期的方法,使用它们可能产生不可预料的结果

使用interrupt方法中断线程,不过interrupt方法不会终止一个正常运行的线程,只会给它设置一个中断标记,需要对其进行判断来停止线程运行

判断线程是否是停止状态有两个方法:

this.interrupted():测试当前线程是否已经中断,是一个静态方法,执行后会将中断标志为false

this.isInterrupted():测试线程是否已经中断,非静态方法,不会清除中断标志

stop()方法已经被作废,因为如果强制让线程停止则有可能使一些清理性的工作得不到完成。另外一个情况就是对锁定的对象进行了“解锁”,导致数据得不到同步的处理,出现数据不一致的问题。

suspend和resume方法会造成公共的同步对象的独占,如PrintlnStream的println方法的独占,使得其他线程无法访问公共同步对象。另外使用这两个方法时也容易造成因为线程的暂停而导致数据不同步的情况。

关键字synchronized的锁是对象锁,而不是把一段代码或者函数当做锁。所以,假如A线程先持有object对象的Lock锁,B线程可以以异步的方式调用object对象中的非synchronized类型的方法,但是如果B线程想要调用object对象中的任何synchronized类型的方法,就需要等待,也就是同步。

synchronized拥有锁重入的功能,也就是说在使用synchronized时,当一个线程得到一个对象锁后,再次请求此对象锁时是可以再次得到该对象锁的。也就是说,在一个synchronized方法的内部调用本类其它synchronized方法时是可以得到锁的。当两个类之间存在继承关系时,子类是可以通过“可重入锁”来调用父类的同步方法的。当一个线程执行的代码出现异常时,其所持有的锁会自动释放。

synchronized(x)格式的写法是将x对象本身作为对象监视器,这样就可以得到以下三个结论:

当多个线程同时执行synchronized(x) {}同步代码块时呈同步效果

当其他线程执行x对象中的同步方法时呈同步效果

当其他线程执行x对象方法里面的synchronized(this)代码块时也呈同步效果

synchronized用在static方法上可以对整个类加锁,就是应用到所有类的对象上面,和synchronized(x.class)的作用一样。子类如果重写了父类的synchronized方法,子类的方法并不继承其synchronized特性,仍需显式地添加synchronized标志。

关键字volatile主要的使用场合是在多个线程中可以感知实例变量被更改了,并且可以获得最新的值使用,也就是用多线程读取实例变量时可以获得最新的值引使用。volatile本身并不处理数据的原子性,而是强制对数据的读写及时影响到主内存。关键字synchronized也具有将工作中的私有变量与公共内存中的变量同步的功能。

在线程调用wait()/notify()方法之前必须要获得该对象的对象级别锁,否则会抛出IllegalMonitorStateException运行时异常。在执行notify()方法之后,当前线程并不马上释放该对象锁,要等到调用notify()方法的线程将程序执行完,也就是退出synchronized代码块之后,当前线程才会释放锁。

join()在内部使用wait()方法进行等待,而synchronized关键字使用的是对象监视器原理作为同步。在某个线程join另一个线程(即等待另一个线程时),如果当前线程(等待别的线程的线程)被中断,则当前线程会抛出异常。

join(long)中的是设定等待的时间,join(long)的功能在是用wait(long)来实现的,所以join(long)方法具有释放锁的特点。而sleep(long)是不会释放锁的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 多线程