多线程同步操作——多线程技术三

线程的同步在多线程中是十分重要的,保证程序中多个线程有序执行不冲突,并且能够达到程序员的要求。

同步的实现方面有两种,分别是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();
	}

}

运行结果:


阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页