您的位置:首页 > 职场人生

黑马程序员:Java基础总结----线程间通信

2013-06-27 19:11 651 查看
黑马程序员:Java基础总结

线程间通信

ASP.Net+Android+IO开发.Net培训、期待与您交流!

线程间通信

其实就是多个线程在操作同一个资源,

但是操作的动作不同。

等待/唤醒机制


也就是常见的生产者消费者问题。

1.当多个生产者消费者出现时,

需要让获取执行权的线程判断标记。

通过while完成。

2.需要将对方的线程唤醒。

仅仅用notify,是不可以的。因为有可能出现只唤醒本方。

有可能会导致,所有线程都等待。

所以可以通过notifyAll的形式来完成 。

JDK1.5版本提供了一些新的对象,优化了等待唤醒机制。

1,将synchronized 替换成了Lock接口。

将隐式锁,升级成了显示锁。

Lock

获取锁:lock();

释放锁:unlock();注意:释放的动作一定要执行,所以通常定义在finally中。

获取Condition对象:newCondition();

2,将Object中的wait,notify,notifyAll方法都替换成了Condition的await,signal,signalAll。

和以前不同是:一个同步代码块具备一个锁,该所以具备自己的独立wait和notify方法。

现在是将wait,notify等方法,封装进一个特有的对象Condition,而一个Lock锁上可以有多个Condition对象。

[align=left]Lock lock = new ReentrantLock();[/align]

[align=left] Condition conA = lock.newCondition();[/align]
[align=left] Condition conB = lock.newCondition();[/align]

[align=left] con.await(); //生产,,消费[/align]

[align=left] con.signal();生产[/align]

[align=left] set()[/align]
[align=left] {[/align]
[align=left] if(flag)[/align]
[align=left] conA.await(); //生产者,[/align]
[align=left] code......;[/align]

[align=left] flag = true;[/align]
[align=left] conB.signal();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] out()[/align]
[align=left] {[/align]
[align=left] if(!flag)[/align]
[align=left] conB.await(); //消费者[/align]

[align=left] code....;[/align]
[align=left] flag = false;[/align]
[align=left] conA.signal();[/align]
[align=left] }[/align]



wait和sleep的区别:


wait:释放cpu执行权,释放同步中锁。

sleep:释放cpu执行权,不释放同步中锁。

synchronized(锁)

{

wait();

}

停止线程:

stop过时。

原理:run方法结束。run方法中通常定义循环,指定控制住循环线程即可结束。

1,定义结束标记。

2,当线程处于了冻结状态,没有执行标记,程序一样无法结束。

这时可以循环,正常退出冻结状态,或者强制结束冻结状态。

强制结束冻结状态:interrupt();目的是线程强制从冻结状态恢复到运行状态。

但是会发生InterruptedException异常。

线程中一些常见方法:

setDaemon(boolean):将线程标记为后台线程,后台线程和前台线程一样,开启,一样抢执行权运行,

只有在结束时,有区别,当前台线程都运行结束后,后台线程会自动结束。

join():什么意思?等待该线程结束。当A线程执行到了B的.join方法时,A就会处于冻结状态。

A什么时候运行呢?当B运行结束后,A就会具备运行资格,继续运行。

加入线程,可以完成对某个线程的临时加入执行。

notify

public final void notify()

唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个
wait
方法,在对象的监视器上等待。
直到当前线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。

此方法只应由作为此对象监视器的所有者的线程来调用。通过以下三种方法之一,线程可以成为此对象监视器的所有者:

通过执行此对象的同步实例方法。
通过执行在此对象上进行同步的
synchronized
语句的正文。
对于
Class
类型的对象,可以通过执行该类的同步静态方法。

一次只能有一个线程拥有对象的监视器。

[align=left]class Res[/align]
[align=left]{[/align]
[align=left] private String name ;[/align]
[align=left] private String sex ;[/align]
[align=left] private boolean flag = false;[/align]

public synchronized void set(String
name,String sex)
[align=left] {[/align]
[align=left] if(flag )[/align]
try{this .wait();}catch(Exception
e){}
this.name =
name;
[align=left] [/align]
this.sex =
sex;
[align=left] flag = true ;[/align]
[align=left] this.notify();[/align]
[align=left] }[/align]
[align=left] public synchronized void out()[/align]
[align=left] {[/align]
[align=left] if(!flag )[/align]
try{this .wait();}catch(Exception
e){}
[align=left] System. out.println(name +"........" +sex );[/align]
[align=left] flag = false ;[/align]
[align=left] this.notify();[/align]
[align=left] }[/align]
[align=left]}[/align]

[align=left]class Input implements Runnable[/align]
[align=left]{[/align]
[align=left] private Res r ;[/align]
[align=left] Input(Res r)[/align]
[align=left] {[/align]
this.r =
r;
[align=left] }[/align]
[align=left] public void run()[/align]
[align=left] {[/align]
int x
= 0;
[align=left] while(true )[/align]
[align=left] {[/align]
[align=left] if(x==0) [/align]
[align=left] r.set( "mike","man" ); [/align]
[align=left] else [/align]
[align=left] r.set( "丽丽","女女女女女" ); [/align]
[align=left] x = (x+1)%2;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]

[align=left]class Output implements Runnable[/align]
[align=left]{[/align]
[align=left] private Res r ;[/align]
[align=left] [/align]
[align=left] Output(Res r)[/align]
[align=left] {[/align]
this.r =
r;
[align=left] }[/align]
[align=left] public void run()[/align]
[align=left] {[/align]
[align=left] while(true )[/align]
[align=left] {[/align]
[align=left] r.out();[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]

[align=left]class InputOutputDemo2[/align]
[align=left]{[/align]
public static void main(String[]
args)
[align=left] {[/align]
[align=left] Res r = new Res();[/align]

[align=left] new Thread(new Input(r)).start();[/align]
[align=left] new Thread(new Output(r)).start();[/align]
[align=left] /*[/align]
[align=left] Input in = new Input(r);[/align]
[align=left] Output out = new Output(r);[/align]

[align=left] Thread t1 = new Thread(in);[/align]
[align=left] Thread t2 = new Thread(out);[/align]

[align=left] t1.start();[/align]
[align=left] t2.start();[/align]
[align=left] */[/align]
[align=left] }[/align]
[align=left]}[/align]

ASP.Net+Android+IO开发.Net培训、期待与您交流!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐