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

黑马程序员:Java基础总结----多线程安全性&同步

2015-01-15 21:50 513 查看
Java对于多线程的安全问题提供了专业的解决方式。

同步代码块

synchronized(对象)
{
需要被同步的代码

}
对象如同锁。持有锁的线程可以在同步中执行。
没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。

火车上的卫生间---经典。

同步的前提:
1,必须要有两个或者两个以上的线程。
2,必须是多个线程使用同一个锁。

必须保证同步中只能有一个线程在运行。

好处:解决了多线程的安全问题。

弊端:多个线程需要判断锁,较为消耗资源,

同步函数

在函数上加上synchronized修饰符即可。
函数需要被对象调用。那么函数都有一个所属对象引用。就是this。
所以同步函数使用的锁是this

class
Ticket
implements
Runnable {

private
static
int
tick
= 100;

public
void
run() {

while
(tick
> 1) {
[align=left] show();[/align]
[align=left] }[/align]
[align=left] }[/align]

public
synchronized
void
show() {

try
{
Thread.
sleep(10);
}
catch
(Exception e) {
[align=left] }[/align]

// synchronized (Ticket.class) {
System.
out.println(Thread.currentThread().getName()
+
".... "
+
tick--);

//tick--;

// }
[align=left] }[/align]
[align=left]}[/align]

public
class
Ts {

public
static
void
main(String[] args) {
Ticket a =
new
Ticket();// 一个实例

new
Thread(a).start();

new
Thread(a).start();
[align=left] }[/align]
[align=left]}[/align]

需求:

银行有一个金库。

有两个储户分别存300员,每次存100,存3次

class
Bank
[align=left]{[/align]

private
int
sum
;

//Object
obj = new Object();

public
synchronized
void
add(int
n)
[align=left] {[/align]

//synchronized(obj)

//{

sum
=
sum
+ n;

try{Thread.sleep(10);}
catch(Exception e){}
System.
out.println("sum="
+sum
);

//}
[align=left] }[/align]
[align=left]}[/align]

class
Cus
implements
Runnable
[align=left]{[/align]

private
Bank
b
=
new
Bank();

public
void
run()
{

for(int
x=0; x<3; x++)
[align=left] {[/align]

b.add(100);
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]

class
BankDemo
[align=left]{[/align]

public
static
void
main(String[] args)
[align=left] {[/align]
Cus c =
new
Cus();
Thread t1 =
new
Thread(c);
Thread t2 =
new
Thread(c);
[align=left] t1.start();[/align]
[align=left] t2.start();[/align]

}
[align=left]}[/align]

如果同步函数被静态修饰

注意:对于static的同步函数,使用的锁不是this。是 类名.class 是该类的字节码文件对象。

涉及到了单例设计模式的懒汉式

通过验证,发现不在是this。因为静态方法中也不可以定义this。

静态进内存是,内存中没有本类对象,但是一定有该类对应的字节码文件对象。

类名.class 该对象的类型是Class

静态的同步方法,使用的锁是该方法所在类的字节码文件对象。 类名.class

public
void
run()
[align=left] {[/align]

if(flag
)
[align=left] {[/align]

while(true
)
[align=left] {[/align]

synchronized(Ticket.class)
[align=left] {[/align]

if(tick
>0)
[align=left] {[/align]

try{Thread.sleep(10);}
catch(Exception e){}
System.
out.println(Thread.currentThread().getName()+
"....code : "+
tick--);
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]

else

while(true
)

show();
[align=left] }[/align]

public
static
synchronized
void
show()
[align=left] {[/align]

if(tick
>0)
[align=left] {[/align]

try{Thread.sleep(10);}
catch(Exception e){}
System.
out.println(Thread.currentThread().getName()+
"....show.... : "+
tick--);
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]

死锁。

同步中嵌套同步


死锁代码一定会写。但开发时一定注意避免

class
MyLock
[align=left]{[/align]

static
Object
locka
=
new
Object();

static
Object
lockb
=
new
Object();
[align=left]}[/align]
while(true
)
[align=left]{[/align]

synchronized(MyLock.lockb)
[align=left] {[/align]
System.out.println(Thread.currentThread().getName()+
"..else lockb");

synchronized(MyLock.locka)
[align=left] {[/align]
System.out.println(Thread.currentThread().getName()+
".....else locka");
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: