线程的同步在多线程中是十分重要的,保证程序中多个线程有序执行不冲突,并且能够达到程序员的要求。
同步的实现方面有两种,分别是synchronized,wait与notify
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
注:wait(),notify():必须在synchronized内部使用。
第一个列子:
运用synchronized同步有两种方式:同步方法,同步方法块
下面运用代码测试来介绍一下synchronized同步的两种方式
public class LockThread2 extends Thread {
//同步方法
public synchronized void synchronizedMethod(){
for (int i = 0; i < 10; i++) {
System.out.println("1");
try {
sleep(500);
} catch (Exception e) {
// TODO: handle exception
}
}
}
//同步方法块
public void synchronizedNei(){
synchronized (this) {
for (int i = 0; i < 10; i++) {
System.out.println("2");
try {
sleep(500);
} catch (Exception e) {
// TODO: handle exception
}
}
}
}
public static void main(String[] args) {
LockThread2 test1=new LockThread2();
Thread lockThread1=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
test1.synchronizedMethod();
}
});
Thread lockThread2=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
test1.synchronizedNei();
}
});
lockThread1.start();
lockThread2.start();
}
}
测试结果:按序输出,先输出1的线程,等1执行结束之后,在执行2的线程
如果去掉关键字synchronized,两个线程将乱序输出。
* 上面两个测试方法,一个同步方法一个同步方法块,并且启动两个线程进行测试,两个线程都获得了对象锁,
* 只有当第一个执行的线程执行完毕之后,第二线程才会继续执行,保证两个线程的执行顺序,即先输出完1,才输出2
* 如果去掉关键字synchronized,两个线程互相执行,谁先抢到了资源谁就执行,即乱序。
第二个列子:
前面介绍了运用同步关键字给对象家对象锁的例子,这个例子是介绍用wait(),notify()给对象加锁的操作。
这个例子是用锁的方法实现输出1212121212,我们都知道如果没有给两个线程进行加锁,那么输出的结果就是乱序。
这个例子的思想就是:给两个线程加相同的锁,第一个进入run方法的是线程t1,之后调用notify唤醒线程,使得t2能够执行到,之后在t1执行完毕之后调用wait进行等待,这样循环下去,就保证了两个线程相互等待运行
package MultiThreed;
public class LockThread extends Thread {
int number;
//定义锁
Object lock;
public LockThread(int i, Object lock) {
this.number = i;
this.lock = lock;
}
/**
* 第一个进入run方法的是线程t1,之后调用notify唤醒线程,使得t2能够执行到,之后在t1执行完毕之后调用wait进行等待
*
*/
@Override
public void run() {
synchronized (lock) {
for (int i = 0; i < 100; i++) {
//lock.notify();
System.out.println(number);
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// TODO Auto-generated method stub
super.run();
}
public static void main(String[] args) {
Object lock = new Object();
LockThread t1 = new LockThread(1, lock);
LockThread t2 = new LockThread(2, lock);
t1.start();
t2.start();
}
}
运行结果: