------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
-线程间通信
分析:线程间的通信其实就是多个线程早操作同一个资源,但操作的动作不同。
线程间通信常用方法:wait(); notify(); notifyAll();
都使用在同步中,因为要对持有监视器(锁)的线程操作,所以要使用在同步中,因为只有同步才具有锁。
为什么这些操作线程的方法要定义在Object类中呢?
因为:这些方法在操作同步中的线程时,都必须要标识它们所操作线程具有的锁。只有
同一个锁上的被等待线程,才可以被同一个锁上的notify()方法唤醒,而不能被不同锁上的唤醒。
也就是说,等待和唤醒线程必须是同一个锁上的,而锁可以是任意对象来充当,所以
可以被任意对象调用的方法就应该定义在Object类中。
class Res {
String name;
String sex;
boolean flag = false;
}
class Input implements Runnable {
private Res r;
public Input(Res r){
this.r= r;
}
public void run(){
int x = 0;
while(true){
synchronized (r) {
if(r.flag)
{
try {
r.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(x==0){
r.name="Amanda";
r.sex="man";
}
else{
r.name="小丽";
r.sex="----女----";
}
x = (x+1)%2;
r.flag = true;
r.notify();
}
}
}
}
class Output implements Runnable {
private Res r;
public Output(Res r){
this.r = r;
}
public void run(){
while(true){
synchronized(r){
if(!r.flag)
{
try {
r.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(r.name+"...."+r.sex);
r.flag = false;
r.notify();
}
}
}
}
public class Day12_01_ThreadCommunicationPractice {
public static void main(String[] args) {
Res r = new Res();
new Thread(new Input(r)).start();
new Thread(new Output(r).start();
}
}
-线程等待唤醒机制
线程之间的关系是平等的,彼此之间并不存在任何依赖,它们各自竞争CPU资源,互不相让,并且还无条件地阻止其他线程对共享资源的异步访问。然而,也有很多现实问题要求不仅要同步的访问同一共享资源,而且线程间还彼此牵制,通过相互通信来向前推进。
常用方法:wait(); notify(); notifyAll();
-多线程通信:生产者消费者
注意点:1、对于多个生产者和消费者,为什么要定义while判断表计?
原因:让被唤醒的线程再一次判断标记。
2、为什么定义notifyAll?
因为需要唤醒对方线程, 如果用nofify,容易出现只唤醒本方线程的情况,导致程序中的所有线程都等待。
//资源
class Resource{
private String name;
private int count= 1;
private boolean flag= false;
public synchronized void set(String name){
while(flag)//为什么是while,而不是if
try{this.wait();} catch(Exception e){}
this.name= name+"---"+count++;
System.out.println(Thread.currentThread().getName()+"生产者...."+this.name);
flag= true;
this.notifyAll();//如果是this.notify(); 会出现什么问题?
}
public synchronized void out(){
while(!flag)
try{wait();} catch(Exception e){}//可以省略this
System.out.println(Thread.currentThread().getName()+"..........消费者"+this.name);
flag= false;
this.notifyAll();//如果是this.notify(); 会出现什么问题?
}
}
//生产者
class Product implements Runnable{
private Resource res;
Product(Resource res){
this.res= res;
}
public void run(){
while(true){
res.set("+商品+");
}
}
}
//消费者
class Consumer implements Runnable{
private Resource res;
Consumer(Resource res){
this.res= res;
}
public void run(){
while(true){
res.out();
}
}
}
public class ProductCustomDemo {
public static void main(String[] args) {
Resource res= new Resource();
new Thread(new Product(res)).start();//生产者1
new Thread(new Product(res)).start();//生产者2
new Thread(new Consumer(res)).start();//消费者1
new Thread(new Consumer(res)).start();//消费者2
}
}
-JDK1.5 中提供多线程升级解决方案
将同步synchronized 替换成现实lock操作
将Object中的wait,notify,notifyall 替换成了condition对象,
该对象可以lock锁,进行获取。
该示例中,实现了本方只唤醒对方操作
//资源
class Resource2 {
private String name;
private int count= 1;
private boolean flag= false;
private Lock lock= new ReentrantLock();
private Condition condition_pro= lock.newCondition();
private Condition condition_con= lock.newCondition();
public void set(String name) throws InterruptedException {
lock.lock();
try{
while(flag)
condition_pro.await();//t1,t2
this.name= name+"--"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
flag= true;
condition_con.signal();
}finally{
lock.unlock();//释放锁的动作一定要执行
}
}
public void out() throws InterruptedException{
lock.lock();
try{
while(!flag)
condition_con.await();
System.out.println(Thread.currentThread().getName()+"------------消费者-"+this.name);
flag= false;
condition_pro.signal();
}finally{
lock.unlock();
}
}
}
//生产者
class Producer2 implements Runnable{
private Resource2 res;
Producer2(Resource2 res){
this.res= res;
}
public void run(){
while(true){
try {
res.set("商品");
} catch (InterruptedException e) {
}
}
}
}
//消费者
class Consumer2 implements Runnable{
private Resource2 res;
Consumer2(Resource2 res){
this.res= res;
}
public void run(){
while(true){
try {
res.out();
} catch (InterruptedException e) {
}
}
}
}
public class ProductCustomDemo2 {
public static void main(String[] args) {
Resource2 r= new Resource2();
Producer2 pro= new Producer2(r);
Consumer2 con= new Consumer2(r);
Thread t1= new Thread(pro);
Thread t2= new Thread(pro);
Thread t3= new Thread(con);
Thread t4= new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}