---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Unity开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ------------------------------------------
多线程的运行出现啦安全问题
问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行啦一部分,还没有执行完。另一个线程参与进来执行。导致共享数据的错误。
解决办法:
对多条操作共享数据的语句,只能让一个线程全执行完。在执行过程中,其他线程不可以参与执行。
Java对于多线程安全问题提供啦专业的解决方式。就是同步代码块
synchronized(对象){ 需要被同步的代码 }//谁在使用共享数据
对象如果有锁。持有锁的线程可以在同步中执行。没有锁的线程即使获取cpu的执行权,也进不去。因为没有获取锁。
同步的前提:
1必须要有两个或两个以上的线程。 2必须是多个线程使用同一个锁。 必须保证同步中只能有一个线程在运行。
好处:解决了多线程的安全问题。 弊端:多个线程需要判断锁,较为消耗资源。
如何找问题(安全问题)
1明确那些代码是多线程运行的代码。 2明确共享数据
3明确多线程代码中哪些语句是操作共享数据
同步函数
同步函数用的是哪个锁呢?
函数需要被对象调用。那么函数都有一个所属对象的引用。就是this,所以同步函数使用的锁是this。
如果同步函数被静态修饰后,使用的锁是什么呢?
静态进内存时,内存中没有本类对象,但是一定有该类对象对应的字节码文件对象。 类名.class 该对象的类型是class
静态的同步方法,使用的锁是该方法所在类的字节码文件对象。 类名.class
死锁
同步嵌套,而且不是同一个锁。
卖票例子
//卖票程序。多个窗口卖票。
/*
创建线程的第二种方法:实现Runnable接口。
1 定义类实现Runnable接口。
2 覆盖Runnable接口中的run的方法。
3 通过Thread类建立线程对象。
4 将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
5 调用Thread的start()方法并调用Runnable接口子类的run方法。
*/
class Ticket implements Runnable
{
private int tick=100;
Object obj=new Object();
public void run()
{
while(true)
{
synchronized(obj)//加入同步代码块,解决多线程安全问题。
{
if(tick>0)
{
System.out.println(Thread.currentThread().getName()+"....sale:"+tick--);
}
}
}
}
}
class TicketDemo1
{
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();
}
}
死锁的例子
//死锁程序
class Test implements Runnable
{
private boolean flag;
Test(boolean flag)
{
this.flag=flag;
}
public void run()
{
if(flag)
{
synchronized(MyLock.locka)
{
System.out.println("if locka");
synchronized(MyLock.lockb)
{
System.out.println("if lockb");
}
}
}else
{
synchronized(MyLock.lockb)
{
System.out.println("else lockb");
synchronized(MyLock.locka)
{
System.out.println("else locka");
}
}
}
}
}
class MyLock
{
static Object locka=new Object();
static Object lockb=new Object();
}
class DeadLockTest
{
public static void main(String[] args)
{
Thread t1=new Thread(new Test(true));
Thread t2=new Thread(new Test(false));
t1.start();
t2.start();
}
}
你要我的锁,我要你的锁。造成死锁。
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Unity开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! --------------------------------