当前位置: 代码迷 >> J2SE >> java同步机制,该如何解决
  详细解决方案

java同步机制,该如何解决

热度:105   发布时间:2016-04-24 01:51:31.0
java同步机制
java中的同步在用起来感觉很简单,但是内部深层的机制是怎么样的呢?就是涉及到“监视器”、“锁”、“对象锁”这些概念的那些知识,能不能详细的解释一下同步的工作原理和流程。
另外,书上说,通过实现Runnable接口来创建多线程能够实现资源共享,以下是一个卖票程序:
Java code
class Myrunnable implements Runnable{    private int ticket=5;    public void run(){    for(int i=0;i<100;i++){      if(ticket>0){        try{          Thread.sleep(300);        }catch(InterruptedException e){          e.printStackTrace();        }        System.out.println("ticket="+ticket--);      }    }  }}public class Demo{    public static void main(String[] args){      MyRunnable myr=New MyRunnable();      Thread t1=New Thread(myr);      Thread t2=New Thread(myr);      Thread t3=New Thread(myr);      t1.start();      t2.start();      t3.start();    }}

程序中加入延迟,会出现票为负数情况,反映出三个线程共享资源,这是不是因为在创建线程时向Thread构造函数中传入的是同一个引用的缘故啊?如果我建立三个Myrunnable的实例,然后传入三个线程的构造函数中,是不是就不会有资源共享了?

------解决方案--------------------
理论部分就让别人来回答吧,我来回答你举的例子

Java code
class MyRunnable implements Runnable{    private int ticket=5;        public void run()    {        for(int i=0;i<100;i++)        {            synchronized(this)    //判断ticket前先将该对象锁住,防止当ticket=1时三个线程又同时减1将ticket变为负数            {                if(ticket>0)                {                    try                    {                        Thread.sleep(300);                    }                    catch(InterruptedException e)                    {                        e.printStackTrace();                    }                    System.out.println("ticket="+ticket--);                }            }        }    }}public class Demo{    public static void main(String[] args)    {        MyRunnable myr=new MyRunnable();        Thread t1=new Thread(myr);        Thread t2=new Thread(myr);        Thread t3=new Thread(myr);        t1.start();        t2.start();        t3.start();    }}
------解决方案--------------------
如果我建立三个Myrunnable的实例,然后传入三个线程的构造函数中,是不是就不会有资源共享了?

什么是共享资源?

在本例中,因为只有一个Myrunnable的实例,因此就只有一个private int ticket=5;也就是说3个线程会同时访问ticket这个成员变量,因此,ticket就是共享资源

如果有三个Myrunnable的实例,每一个线程一个实例,当然就不存在共享资源这个说法了,就不会发生线程安全问题了。

------解决方案--------------------
嗯,我和楼主在看同一本书。我想借机问一下,如果是多个Myrunnable接口的实例,将ticket设置为static作为共享数据可以吗?
------解决方案--------------------
探讨

嗯,我和楼主在看同一本书。我想借机问一下,如果是多个Myrunnable接口的实例,将ticket设置为static作为共享数据可以吗?

------解决方案--------------------
探讨
将ticket设置为static作为共享数据,就需要做同步,否则就会出现线程安全问题
synchronized(Myrunnable.class){}
  相关解决方案