A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© 914360849 中级黑马   /  2015-5-25 22:34  /  353 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

多线程安全问题。

当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。

解决方法:对多条操作共享数据的语句,只能让一个线程都执行完;在执行过程中,其他线程不可以参与执行。

Java对于多线程的安全问题提供了专业的解决方式。就是同步代码块。

Synchronized(对象)

{ 需要被同步的代码;

}

对象如同锁,持有锁的线程可以在同步中执行。

没有持有锁的线程即使获取CPU执行权,也近不去,因为没有获取到锁。

经典例子:火车上的卫生间。

同步的前提:

1,  至少有两个线程。

2,  必须是多个线程使用同一个锁。

必须保证同步中只有一个线程在运行。

好处:解决了多线程的安全问题。

弊端:多个线程需要判断锁,较为消耗资源。

同步有两种表现形式:同步函数和同步代码块。

同步函数使用的是哪一个锁呢?

函数需要被对象调用,那么函数都有一个所属对象的引用:就是this。所以同步函数使用的锁是this。

多窗口同时买票:

class Ticket implements Runnable

{

         private   int tick=100;

         //Object obj =new Object();

         boolean flag=true;

         public  void run()

         {

                   if(flag)

                   {

                            while(true)

                            {

                                     synchronized(this)

                                     {

                                               if(tick >0)

                                               {

                                                        System.out.println(Thread.currentThread().getName()+" code: "+tick--);

                                               }

                                     }

                            }

                   }

                   else

                   {

                            while(true)

                                     show();

                   }

         }


         public synchronized void show()

         {

                   if(tick >0)

                            {

                                     System.out.println(Thread.currentThread().getName()+" ...show... "+tick--);

                            }

         }

}

class  TicketDemo2//ThisLockDemo

{

         public static void main(String[] args)

         {

                   Ticket t =new Ticket();

Thread t1=new Thread (t);//

                   Thread t2=new Thread (t);//

t1.start();

t.flag=false;

t2.start();

         }

}

当同步函数被静态修饰后,使用的锁是什么?

不是this,因为静态方法中不可以定义this。

静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。


静态的同步方法,使用的锁是该方法所在类的字节码文件对象。类名.class。

2 个回复

倒序浏览
路过看看
回复 使用道具 举报
欢迎 提问题,多多交流
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马