多个线程共享数据的方式

讨论多个线程共享数据,其实就是讨论多个线程如何对同一个数据进行操作。

另外,从今天开始,我会将我博客中涉及到的源代码放到我的github中。

本文源代码下载:My Tracks

方式有很多,这里列出2种:

1.每个线程执行的代码相同

如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个对象中有那个我们需要共享的数据,例如我们的卖票系统。

示例Demo:



public class ManyCenjoyOneob
{

    public static void main(String[] args)
    {
        AllenjoyOb demo = new AllenjoyOb();

        Thread th1 = new Thread(demo);
        Thread th2 = new Thread(demo);

        th1.start();
        th2.start();
    }

}
class AllenjoyOb implements Runnable
{

    private int data = 0;

    @Override
    public void run()
    {
        increment();

    }

    private void increment()
    {
        data++;
    }
}

分析:我们将data作为共享数据,然后作为Runnable对象的一个成员变量,构造线程的时候使用同一个Runnable对象,然后就可以使用多线程共同操作同一个data了。

2.共享数据封装在另外一个实现Runnable接口的类中

示例Demo:


public class ManyCenjoyOneob
{

    public static void main(String[] args)
    {
        //第一种方式
        AllenjoyOb demo = new AllenjoyOb();

        Thread th1 = new Thread(demo);
        Thread th2 = new Thread(demo);

        th1.start();
        th2.start();

        //第二种方式
        int data = 0;

        Thread thA = new Thread(new XXXX2(data));
        Thread thB = new Thread(new XXXX2(data));

        thA.start();
        thB.start();
    }

}
//第一种方式使用的类代码
class AllenjoyOb implements Runnable
{

    private int data = 0;

    @Override
    public void run()
    {
        increment();

    }

    private void increment()
    {
        data++;
    }
}

//第二种方式使用的类的代码
class XXXX2 implements Runnable
{
    private int data2 = 0;
    public XXXX2(int data2)
    {
        this.data2 = data2;
    }

    @Override
    public void run()
    {
        increment2();
    }

    private void increment2()
    {
        data2++;
    }
}

最后,我们来看一个常见的面试题:

题目如下:设计四个线程,其中2个线程每次对j增加1,另外2个对j每次减少1。

分析:依照前面我们对代码分块的原则,我们将线程分成2部分,一部分是来负责增加操作,另一部分是负责减少操作。为了使代码看起来条理清楚,我们将增加和减少这2个操作也独立成方法。然后还有主程序用来调用线程。另外,还有j需要线程共享,于是我们将j放在类的成员变量中,用内部类的方式来操作j,毕竟内部类可以操作类的成员变量。代码如下:


public class FourThreadIncJDecJ
{

    private int j = 0;   //将j作为主类的成员变量,

    public static void main(String[] args)
    {
        FourThreadIncJDecJ demo = new FourThreadIncJDecJ();//实例化一个主类对象,一是可以方便创建内部类对象,二是可以得到一个j数据

        Inc incRunnable = demo.new Inc();                       //这里应当注意,内部类对象的创建依赖于寄生的那个主类的对象!
        Dec decRunnable = demo.new Dec();

        for(int i = 0;i<2;i++)
        {

            Thread thread = new Thread(incRunnable);
            thread.start();

            thread = new Thread(decRunnable);
            thread.start();


        }

    }

    //increment Operation
    public synchronized void IncOp()
    {
        j++;

        System.out.println(Thread.currentThread().getName()+"+ inc :"+j);
    }

    //Dec Operation
    public synchronized void DecOp()
    {
        j--;
        System.out.println(Thread.currentThread().getName()+"+ dec :"+j);
    }



    class Inc implements Runnable
    {

        @Override
        public void run()
        {
            IncOp();
        }
    }

    class Dec implements Runnable
    {
        @Override
        public void run()
        {
            DecOp();
        }
    }
}

你可能感兴趣的:(●,JAVA,进阶)