java_第13章 多线程(2)
13.4 线程的同步
线程间共享代码和数据可以节省系统开销,提高程序运行效率,但同时也导致了数据的“访问冲突”问题,如何实现线程间的有机交互、并确保共享资源在某些关键时段只能被一个线程访问,即所谓的“线程同步”(Synchronization)就变得至关重要
多个线程间共享的数据称为临界资源(Critical Resource),由于是线程调度器负责线程的调度,程序员无法精确控制多线程的交替顺序。因此,多线程对临界资源的访问有时会导致数据的不一致行
为了避免线程的随即执行和它不受控制,也就是为了避免这个临界资源问题,最基本,最简单的就是引用同步关键字synchronized,它的作用就是:对于同一个对象(不是一个类的不同对象),当多个线程同时执行该代码块或方法时,必须依次执行。
同步的两种表现形式:
1.同步代码块
synchronized(对象){
需要同步的代码
}
2.同步函数: 使用的锁是this
public synchronized void show(){
}
同步的作用:避免线程的安全隐患
例:
package com.hbsi;
public class SaleTicket implements Runnable{
/**
* @param args
*/
private int ticket=100;
//Object obj=new Object();
public static void main(String[] args) {
SaleTicket st=new SaleTicket();
Thread t1=new Thread(st);
Thread t2=new Thread(st);
t1.start();
t2.start();
}
public synchronized void run(){
while(true){
//synchronized(obj){
if(ticket>0){
/*try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
System.out.println(Thread.currentThread().getName()+"..."+ticket--);
}
}
}
}
其执行结果为:
Thread-1...100
Thread-1...99
Thread-1...98
Thread-1...97
Thread-1...96
Thread-1...95
Thread-1...94
Thread-1...93
Thread-1...92
Thread-1...91
Thread-1...90
Thread-1...89
Thread-1...88
Thread-1...87
Thread-1...86
Thread-1...85
Thread-1...84
Thread-1...83
Thread-1...82
Thread-1...81
Thread-1...80
Thread-1...79
Thread-1...78
Thread-1...77
Thread-1...76
Thread-1...75
Thread-1...74
Thread-1...73
Thread-1...72
Thread-1...71
Thread-1...70
Thread-1...69
Thread-1...68
Thread-1...67
Thread-1...66
Thread-1...65
Thread-1...64
Thread-1...63
Thread-1...62
Thread-1...61
Thread-1...60
Thread-1...59
Thread-1...58
Thread-1...57
Thread-1...56
Thread-1...55
Thread-1...54
Thread-1...53
Thread-1...52
Thread-1...51
Thread-1...50
Thread-1...49
Thread-1...48
Thread-1...47
Thread-1...46
Thread-1...45
Thread-1...44
Thread-1...43
Thread-1...42
Thread-1...41
Thread-1...40
Thread-1...39
Thread-1...38
Thread-1...37
Thread-1...36
Thread-1...35
Thread-1...34
Thread-1...33
Thread-1...32
Thread-1...31
Thread-1...30
Thread-1...29
Thread-1...28
Thread-1...27
Thread-1...26
Thread-1...25
Thread-1...24
Thread-1...23
Thread-1...22
Thread-1...21
Thread-1...20
Thread-1...19
Thread-1...18
Thread-1...17
Thread-1...16
Thread-1...15
Thread-1...14
Thread-1...13
Thread-1...12
Thread-1...11
Thread-1...10
Thread-1...9
Thread-1...8
Thread-1...7
Thread-1...6
Thread-1...5
Thread-1...4
Thread-1...3
Thread-1...2
Thread-1...1
死锁
两个线程A、B用到同一个对象s(s为共享资源),且线程A在执行中要用到B运行后所创造的条件。在这种前提下A先开始运行,进入同步块后,对象s被锁定,接着线程A因等待B运行结束而进入阻塞状态,于是B开始运行,但因无法访问对象s,线程B也进入阻塞状态,等待s被线程A解锁。最终的结果:两个线程互相等待,都无法运行。
例:
public class DeadLock {
/**
* @param args
*/
public static void main(String[] args) {
Demo6 d1=new Demo6(true);
Demo6 d2=new Demo6(false);
Thread t1=new Thread(d1);
Thread t2=new Thread(d2);
t1.start();
t2.start();
}
}
class MyLock{
static MyLock lock1=new MyLock();
static MyLock lock2=new MyLock();
}
class Demo6 implements Runnable{
//String str1=new String("aaa");
//String str2=new String("bbb");
private boolean flag;
public Demo6(boolean flag){
this.flag=flag;
}
@Override
public void run() {
if(flag){
synchronized(MyLock.lock1){
System.out.println(Thread.currentThread().getName()+"...if...str1");
synchronized(MyLock.lock2){
System.out.println(Thread.currentThread().getName()+"...if...str2");
}
}
}else{
synchronized(MyLock.lock2){
System.out.println(Thread.currentThread().getName()+"...else...str2");
synchronized(MyLock.lock1){
System.out.println(Thread.currentThread().getName()+"...else...str1");
}
}
}
}
}