黑马程序员技术交流社区
标题:
关于多线程的安全问题
[打印本页]
作者:
夏儒日
时间:
2012-7-2 22:20
标题:
关于多线程的安全问题
一个关于多线程的安全问题.一个多窗口同时买票的程序.为什么用同步代码块解决多线程安全问题的时候,在创建Object对象的两个位置输出结果不一样呢?放在位置1能解决安全性问题,而在位置2创建Object对象不能解决安全性问题呢?代码如下,求各位大神指点迷津!谢谢~~~
class Ticket implements Runnable
{
private static int tick=100;
Object obj=new Object();//创建Object对象位置1
public void run()
{
while(true)
{
//Object obj=new Object();创建Object对象位置2
synchronized(obj)
{
if (tick>0)
{
try
{
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"...sale.."+tick--);
}
catch (Exception e)
{
System.out.println("错误了!!");
}
System.out.println(Thread.currentThread().getName()+"...sale.."+tick--);
}
}
}
}
}
class TicketDemo2
{
public static void main(String[] args)
{
Ticket t=new Ticket();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
Thread t4=new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
作者:
蒋映辉
时间:
2012-7-2 22:27
因为你是针对obj进行锁定 如果在1位置 整个类中只有一个obj 而在2位置 没调用一次 就会新建一个obj 每一个线程的obj都不一样 所以就不能锁定了
作者:
yulu53
时间:
2012-7-2 22:27
这个问题 毕老师的视频讲的很清楚,不懂再看一遍吧
作者:
夏儒日
时间:
2012-7-2 22:32
刚才一着急忘了把try里面的打印语句删了,不过无伤大雅,主要问题还是创建对象的位置不同而导致的问题,想不明白,忘大神赐教.
作者:
金龙
时间:
2012-7-3 02:52
同步的关键在于,是否使用同一把锁,即同步的锁是同一个对象。你定义在循环里面,则每次都会新建一个Object对象,从而导致不是一把锁,当然实现不了同步了
作者:
王达
时间:
2012-7-3 08:18
确定是否在一个同步内,关键在于是否是同一个锁,也就是synchronized()中传入的是否是同一个对象,如果obj定义在2的位置,那么每次开始循环都会建立一个新的obj,也就是说每次循环所用的锁都不是同一个。 现在有lock了为啥不要用lock呢。。。
作者:
刘建龙
时间:
2012-7-3 15:57
class Ticket implements Runnable
{
private static int tick=100;
Object obj=new Object();//创建Object对象位置1,
成员变量,当创建对象后t后,对象中只有一个obj,也就是只有一把锁
public void run()
{
while(true)
{
//Object obj=new Object();创建Object对象位置2,
此位置时,每次调用run方法都会重新new一个obj,也就是不是同一把锁,所以没有起到同步的作用。同步需要共享同一把锁的。
synchronized(obj)
{
if (tick>0)
{
try
{
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"...sale.."+tick--);
}
catch (Exception e)
{
System.out.println("错误了!!");
}
System.out.println(Thread.currentThread().getName()+"...sale.."+tick--);
}
}
}
}
}
class TicketDemo2
{
public static void main(String[] args)
{
Ticket t=new Ticket();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
Thread t4=new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
作者:
柯玲
时间:
2012-7-13 10:11
在(1)位置处的obj是成员变量,是程序中的共享数据,同ticket一样,是堆内存中的共享数据。 在启动两个线程的时候,保证了是使用的同一个对象(锁),符合同步的前提:“多个线程使用同一个锁”,其实就可以把定义在此处的obj想象成ticket呀!
因为run()是每个线程子类必须实现的方法,main()中通过Ticket t=new Ticket()创建了一个新线程, 而(2)位置处的obj处于run方法内,当线程运行起来以后,栈内存会给每个在运行的线程分配一个独立的内存空间,这样四个线程中就有四个obj。四个线程不是持有相同的锁,违反了“多个线程使用同一个锁”,(2)位置处就不能解决安全性问题了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2