黑马程序员技术交流社区
标题:
多线程_07_同步代码块
[打印本页]
作者:
Tauruszzy
时间:
2015-5-13 15:10
标题:
多线程_07_同步代码块
为了解决多线程的安全问题,为什么这么说呢?
请看代码一的执行结果:
代码一
class Ticket implements Runnable
{
private int tick=100;
public void run()
{
while(true)
{
if(tick>0)
{
try
{
Thread.sleep(10);
}
catch (Exception e)
{
}
System.out.println(Thread.currentThread().getName()+"...sale:"+tick--);
}
}
}
}
class TicketDemo
{
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();
}
}
复制代码
代码一执行结果:
Thread-0...sale:10
Thread-2...sale:9
Thread-3...sale:8
Thread-1...sale:7
Thread-0...sale:6
Thread-2...sale:5
Thread-3...sale:4
Thread-1...sale:3
Thread-0...sale:2
Thread-2...sale:1
Thread-3...sale:0
Thread-0...sale:-1//1
Thread-1...sale:-2//2
复制代码
上面的售票例子中出现了负值,与事实相悖,原因是多个线程共享的数据出现了问题,为了解决这个问题,我们需要在共享的语句范围内确保只有一个线程在运行,当一个线程运行结束本次执行权后,再允许下一个线程的运行,这里引入同步代码块的机制,看下面的代码:
代码2
class Ticket implements Runnable
{
private int tick=100;
Object obj=new Object();//定义需要传入的对象
public void run()
{
while(true)
{
synchronized(obj)//同步代码块
{
if(tick>0)
{
try
{
Thread.sleep(10);//睡眠10毫秒
}
catch (Exception e)
{
}
System.out.println(Thread.currentThread().getName()+"...sale:"+tick--);
}
}
}
}
}
class TicketDemo
{
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();
}
}
复制代码
总结:
/*
对象如同锁。持有锁的线程可以在同步中执行。
没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
同步的前提:
1,必须要有两个或者两个以上的线程。
2,必须是多个线程使用同一个锁。
必须保证同步中只能有一个线程在运行。
好处:解决了多个线程的安全问题。
弊端:多个线程需要判断锁,较为消耗资源。
-------------黑马视频--毕老师
*/
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2