java多线程编程核心技术前夜3(线程间的通信)

1.等待通知机制(wait/notify):这两个方法都必须在synchroized中执行,因为这两个方法都必须获得锁,wait方法返回之前,释放对象锁,使这个线程与其他线程重新争夺某一个锁。notify通知想要获得这个对象锁的所有对象,当前线程将要释放这个对象锁,但是不是立即释放对象,而是执行synchroized完成后才释放对象锁。如果一个线程从wait状态获得了锁,程序完成之后没有调用notify语句,那么那些处于wait中的线程永远得不到这个对象的锁,除非显示调用notify或则notifyAll方法。总结一句话:wait使线程暂停运行,notify使线程继续运行。

2.notify()方法和notifyAll()方法:两个方法都是通知处于wait()状态的线程,对象锁将会被释放,但是不是马上被释放只是通知线程对象锁将被释放。执行完synchroized代码块中的代码后对象锁才会被释放。notify方法通知一个线程此对象锁将被释放,而notifyAll()通知所有处于wait()状态的线程。

3.对处于wait方法中的线程调用interrupt()中断。对象锁也会被释放。

4.wait(long x)方法表示在x毫秒之后若对象还可以获得,则自动唤醒这个线程。

5.线程的假死状态:所有线程都进入了waiting状态。之后所有线程都不能执行了

6.join()方法:一个线程a中创建出一个线程b,并且b.join()。这时a线程会被无限期的阻塞,知道b线程被销毁才继续执行a线程后边的代码。

7.join方法遇到interrupt异常。线程b创建线程a,并执行a.join();同时在外部调用b.interrupt()方法,这时b线程就会出现异常,但a线程无影响。

8.join(long x)和sleep(long x)的区别:都是让当前主线程暂停执行x毫秒,但是join会释放所修饰对象的锁,其他线程就可以调用被修饰线程的同步方法了。

9.lock对象和ReentrantLock()、Condition的使用:

public class myservice{
private Lock lock=new ReentranLock();
public Condition conditionA=lock.newCondition();
public Condition conditionB=lock.newCondition();
public void waitA(){
try{
lock.lock();
System.out.println("conditonA test get into lock");
conditionA.await();
catch(InterruptedException e){
e.printStackTrack();
}finally{lock.unlock();}
}
public void signalAll_A(){
try{lock.lock();
conditionA.signalAll();
}finally{lock.unlock();}
}
}
}

如上代码:首先声明了两个condition变量,这个两个变量都是有lock对象创建的。conditionA和conditionB的作用是分别设置通知不同的线程唤醒状态。假如有四个线程,两个线程是用conditionA进行await的,另外两个是用conditionB进行await的。那么当调用conditionA.signalAll()方法的时候,唤醒的就是因conditionA.await()方法暂停的线程。有了wait/notify。为什么还需要在jdk5中增加lock锁加conditon对象来实现同步呢?因为wait/notify只能通知所有处于waiting状态的线程。而lock加condition的方式就可以有选择的通知哪一部分线程可以醒过来。

10.公平锁和非公平所:公平锁-先到的线程先获得锁。非公平锁-线程随机获得锁(有jvm调度)Lock lock=new RenntranLock(true)这是创建的公平锁,Lock lock=new RenntranLock(false)创建非公平锁。创建是否为公平锁不同之处是传入的boolean参数。

扫描二维码关注公众号,回复: 1552418 查看本文章

11.ReentrantReadWriteLock()读写锁:ReentrantReadWriteLock lock=new ReentranReadWtiteLock();lock.readLock.lock()为锁定了读操作;lock.writeLock.lock()为锁定了写操作;多线程读操作是共享的,多线程写写、读写、写读都是互斥的。

12.Timer用于定时执行任务的类。Timer timer=new Timer(boolean x)布尔类型决定了是否将这个计时任务设置为守护线程。timer的使用1:timer.schedule( TimerTask task,long time).其中task为一个继承TimerTask类的子类对象。如果time的设置早于当前时间则立即运行task任务。


猜你喜欢

转载自blog.csdn.net/bigseacoming/article/details/80384410