您的位置:首页 > 职场人生

黑马程序员 Java基础学习笔记 线程安全问题

2014-03-02 19:57 357 查看
---------------------- <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>、期待与您交流! --------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: