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

黑马程序员-学习日记(多线程间的通信)

时间:2015-07-13 23:54:18      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:

 ------Java EE培训、Android培训、iOS培训、期待与您交流! -------

示例:

//将资源封装成对象
class Resour
{
    String name;
    String gender;
}

//将线程执行的任务封装成对象
class Input implements Runnable
{
       private Resour r;
    Input(Resour r)
    {
        this.r = r;
    }
    public void run()
    {
        int x =0;
        while(true)
        {
            if(x==0)
            {
                r.name = "Travis";
                r.gender = "male";
            }
            else
            {
                r.name = "张妙";
                r.gender = "女性";
            }
            x = (x+1)%2;    
        }
    }
}

class Output implements Runnable
{
    private Resour r;
    Output(Resour r)
    {
        this.r = r;
    }
    public void run()
    {
        while(true)
        {
            System.out.println(r.name+" "+r.gender);
        }
    }
}

class myLock
{
    static Object lockA = new Object();
    static Object lockB = new Object();
}

 class mlpcDemo 
{
    public static void main(String[] args) 
    {
        Resour r = new Resour();
        Input in = new Input(r);
        Output out = new Output(r);
        Thread th0 = new Thread(in);
        Thread th1 = new Thread(out);
        
        th0.start();
        th1.start();
    }
}

技术分享

于是,我们给赋值的代码块加上同步。这里要注意必须明确哪些代码是要同步的。

//将资源封装成对象
class Resour
{
    String name;
    String gender;
}

//将线程执行的任务封装成对象
class Input implements Runnable
{
    private Resour r;
    Object obj = new Object();
    Input(Resour r)
    {
        this.r = r;
    }
    public void run()
    {
        int x =0;
        synchronized(obj)
        {
           while(true) { if(x==0) { r.name = "Travis"; r.gender = "male"; } else { r.name = "张妙"; r.gender = "女性"; } x = (x+1)%2; } } } } class Output implements Runnable { private Resour r; Output(Resour r) { this.r = r; } public void run() { while(true) { System.out.println(r.name+" "+r.gender); } } } class myLock { static Object lockA = new Object(); static Object lockB = new Object(); } class mlpcDemo { public static void main(String[] args) { Resour r = new Resour(); Input in = new Input(r); Output out = new Output(r); Thread th0 = new Thread(in); Thread th1 = new Thread(out); th0.start(); th1.start(); } }

表面上看,赋值代码块被加上了同步,但运行的结果依然出现了姓名和性别乱搭配的情况。

于是分析原因,定义同步有两个前提,首先Input和Output这两个线程并未使用同一个锁。

其次,仔细观察下列代码:

Thread th0 = new Thread(in);
Thread th1 = new Thread(out);
th0.start();
th1.start();

无论Input还是Output都只有一条线程在执行!

 不过,解决这个问题也十分容易。给不同线程的同步函数加上相同的锁。

需注意的错误:

 1 public void run()
 2     {
 3         int x =0;
 4         synchronized(r)  //这样会使得线程永远走此同步函数内的代码块
 5         {
 6                 while(true)
 7                 {
 8                 if(x==0)
 9                 {
10                     r.name = "Travis";
11                     r.gender = "male";
12                 }  
13                 else
14                 {
15                     r.name = "张妙";
16                     r.gender = "女性";
17                 }
18                 x = (x+1)%2;    
19             }    
20         }        
21     }   

 

黑马程序员-学习日记(多线程间的通信)

标签:

原文地址:http://www.cnblogs.com/tozr/p/4151513.html

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