Java线程——线程之间的数据共享

 
在 Java 传统线程机制中的共享数据方式,大致可以简单分两种情况:
➢ 多个线程行为一致,共同操作一个数据源。也就是每个线程执行的代码相同,可以使用同一个 Runnable 对象,这个 Runnable 对象中有那个共享数据,例如,卖票系统就可以这么做。
➢ 多个线程行为不一致,共同操作一个数据源。也就是每个线程执行的代码不同,这时候需要用不同的Runnable 对象。例如,银行存取款。 
 
实例1:多个线程行为一致共同操作一个数据
 
  如果每个线程执行的代码相同,可以使用同一个 Runnable 对象,这个 Runnable 对象中有那个共享数据,例如,买票系统就可以这么做。
package com.itheima.gan;
//买票系统
//共享数据类
class  ShareDate{
    private int num=10;   //10张票
    
    public synchronized void inc() {
        num++;
        System.out.println(Thread.currentThread().getName()+
                ": invoke inc method num="+num);
        try {
            //线程休眠1s
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 多线程类
 * @author 12428
 *
 */
public class RunnableCusToInc implements Runnable{

    private ShareDate shareDate;
    //构造方法,将数据传递进去
    public RunnableCusToInc(ShareDate shareDate) {
        this.shareDate=shareDate;
    }
    //线程应该做的事
    @Override
    public void run() {
        for(int i=0;i<5;i++) {
            shareDate.inc();
        }
        
    }

    public static void main(String[] args) {
        ShareDate shareDate=new ShareDate();
        
        for(int i=0;i<4;i++) {
            new Thread(new RunnableCusToInc(shareDate),"线程"+i).start();
        }
    }
}

 

实例2:多个线程行为不一致共同操作一个数据 

如果每个线程执行的代码不同,这时候需要用不同的 Runnable 对象,有如下两种方式来实现这些 Runnable 对象之间的数据共享

 (1)将共享的数据放到一个对象中,在把这个对象逐一传递给各个Runnable对象,每个线程对该数据的操作也放在这个对象的不同方法中,这样说实现容易针对对该数据进行的各个操作的互斥和通信。

package com.itheima.gan;

class RunnableCusToDec implements Runnable {
    private ShareDate1 shareDate;

    public RunnableCusToDec(ShareDate1 shareDate) {
        this.shareDate = shareDate;
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            shareDate.dec();
        }
    }
}


public class RunnableCusToInc2 implements Runnable {

    private ShareDate1 shareDate;

    public RunnableCusToInc2(ShareDate1 shareDate) {
        this.shareDate = shareDate;
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            shareDate.inc();
        }
    }

    public static void main(String[] args) {
        ShareDate1 shareDate1=new ShareDate1();
        for(int i=0;i<4;i++) {
            if(i%2==0) {
                new Thread(new RunnableCusToInc2(shareDate1),"Thread"+i).start();
            }else {
                new Thread(new RunnableCusToDec(shareDate1),"Thread"+i).start();
            }
        }
    }
}

/*
 * 共享数据类
 */
class ShareDate1 {
    private int num = 10;

    public synchronized void inc() {
        num++;
        System.out.println(Thread.currentThread().getName() + ": invoke inc method num=" + num);

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void dec() {
        num--;
        System.err.println(Thread.currentThread().getName() + ": invoke dec method num =" + num);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

 

  运行结果如图:

       

 

(2)将这些 Runnable 对象作为某一个类中的内部类,共享数据作为这个外部类中的成员变量,每个线程对共享数据的操作方法也分配给外部类,以便实现对共享数据进行的各个操作的互斥和通信,作为内部类的各个Runnable 对象调用外部类的这些方法。

package com.itheima.gan;

public class RunnableTest {
    public static void main(String[] args) {
        //公共数据
        final ShareDate2 shareDate=new ShareDate2();
        for(int i=0;i<4;i++) {
            if(i%2==0) {
                new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
                        for(int i=0;i<5;i++) {
                            shareDate.inc();
                        }
                        
                    }
                },"Thread "+i).start();
            }else {
                new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
                        for(int i=0;i<5;i++) {
                            shareDate.dec();
                        }
                        
                    }
                }).start();
            }
        }
    }
}

//公共数据类
class ShareDate2{
    
    private int num=10;
    
    public  synchronized void inc() {
        num++;
        System.err.println(Thread.currentThread().getName()+" : invoke inc method  num = "+num);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public synchronized void dec() {
        num--;
        System.out.println(Thread.currentThread().getName()+" : invoke dec method num = "+num);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
}

 

 

  运行结果如图:

    

 

 

posted @ 2019-12-04 10:29  颗就完了  阅读(2635)  评论(1编辑  收藏  举报