多线程安全问题。
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。
解决方法:对多条操作共享数据的语句,只能让一个线程都执行完;在执行过程中,其他线程不可以参与执行。
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。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |