码迷,mamicode.com
首页 > 编程语言 > 详细

JavaSE:多线程补充--线程通信

时间:2015-03-12 01:02:15      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:javase   多线程   记录   

线程通信我认为是多线程中最难掌握的部分了,这里通过两个例子来说明一下。
第一个:
使用两个线程打印 1-100. 线程1, 线程2 交替打印

public class Print implements Runnable{
    int i = 1;
    public void run(){
        while(true){
            synchronized(this){
                if(i<100){
                    notify();
                    System.out.println(Thread.currentThread().getName() + ":" + i);
                    i++;
                    try{
                        wait();
                    } catch(Exception e){
                        System.out.println(e.getMessage());
                    }   
                } else {
                    break;
                }
            }
        }
    }
}
public static void main(String[] args){
    Print p = new Print();
    Thread t1 = new Thread(p);
    Thread t2 = new Thread(p);
    t1.start();
    t2.start();
}

第二个例子:
生产者消费者:
生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,店员一次只能持有固定数量的产品(比如:20),
如果生产者试图生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;
如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。

问题分析:
1.是否涉及到多线程?是,生产者和消费者
2.是否涉及到多线程同步?是,生产者消费者操作共享数据
3.是否有线程通信?是。

public class Productor implements Runnable{
    Clerk clerk = null; //要保证这个对象是共享数据,在它创建对象的时候,给它传同一个clerk对象
    public Productor(Clerk clerk){
        this.clerk = clerk;
    }
    public void run(){
        //无限制的生产产品
        //大家想想,直接在这里写生产合适吗?
        //直接在这里写,无法操作共享数据了。所以我们直接让clerk增加产品就好。
        while(true){
            //如果出现问题,我们把这个问题放大。
            try{
                Thread.currentThread.sleep(10);
            }catch(Exception e){
                ......
            }//还记得昨天我说的吗?这个sleep写在这里必须处理
            clerk.addProduct();
        }
    }
}

同样的消费者我就不详细写了,和上面的一样。

public class Consumer implements Runnable{
    ......
    public void run(){

    ....
    clerk.getProduct();

    }
}

来写Clerk类:

public class Clerk{
    int product;//这就是我们要操作的共享数据 
    public synchronized void addProduct(){
        if(product >= 20){
            try{
            wait();//生产超过20个了,我们等消费者拿走再生产
            }catch (){
                ....
            }
        }else{
            System.out.println(Thread......getName() + "生产了一个产品,现在共" + product + "个");
            product++;
            notify();//或许这个时候,因为没有产品,消费者正在等待,我们生产了产品,就把它唤醒,可以拿走了。
        }
    }

    //与上面类似。。。。
    public synchronized void getProduct(){
        if(product <= 0){
            wait();
            ......
        }else{
            ......
        }
    }
}

测试类我就不写了,可以自己试试。

至此,关于多线程的回顾就结束了,我们需要学习的是,处理多线程的思路,我上面已经说过。
问题不明显的时候,我们通过sleep()方法可以将问题放大。
但是我们在处理这类问题的时候,我们可以将这些不相关的东西删掉。关注问题本质,比如是否发生了共享数据的交叉,死锁等问题。
还有就是,注意理解线程的生命周期。恩,就这些问题。
明天来回顾反射,和写我的毕业设计开题报告。

JavaSE:多线程补充--线程通信

标签:javase   多线程   记录   

原文地址:http://blog.csdn.net/sloverpeng/article/details/44208405

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!