实现两个线程交替执行

题目:使用多线程实现输出的效果为: 1 -1 2 -2 3 -3 4 -4 …

方法一:公平锁解决两个线程交替执行

package com.thread.synchronizedDemo.lock;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 007
 * @ClassName 类名称
 * @Description 类描述
 */

public class LockDemo implements Runnable {
	
	// 定义一个数用来交替更改数字的正负号
	private int j = 1;
	// 定义公平锁,用来是线程1和线程2交替执行
	ReentrantLock lock = new ReentrantLock(true);

	@Override
	public void run() {
		for(int i = 1; i < 100; i++){
			//获取锁
			lock.lock();
			try{
				System.out.println(Thread.currentThread().getName()+" "+i*j);
				j=-j;
			}finally{
				//释放锁
				lock.unlock();
			}
		}
	}

}

package com.thread.synchronizedDemo.lock;
/**
* @author 007
* @ClassName 类名称
* @Description 类描述
*/

public class TestLock {
	public static void main(String[] args) {
		//创建对象
		LockDemo lockDemo = new LockDemo();
		//创建两个线程,启动两个线程
		new Thread(lockDemo,"线程1").start();
		new Thread(lockDemo,"线程2").start();
	}
}

结果为:

线程1 1
线程2 -1
线程1 2
线程2 -2
线程1 3
线程2 -3
线程1 4
线程2 -4
线程1 5
线程2 -5
线程1 6
线程2 -6
线程1 7
线程2 -7
线程1 8
线程2 -8
线程1 9
线程2 -9
线程1 10
线程2 -10
线程1 11
........

方法二:采用wait()和notify()方法解决两个线程交替执行

public class Demo11 {
	public static void main(String[] args) {
		// 创建锁对象
		final Object object = new Object();
		// 创建线程A,开启线程
		new Thread(new Runnable() {

			@Override
			public void run() {
				for (int i = 1; i < 100; i++) {
					synchronized (object) {
						try {
							System.out.println(Thread.currentThread().getName() + " " + i);
							// 进入等待状态,并释放锁
							object.wait();// 无线等待状态
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

				}
			}
		}, "A").start();

		// 创建线程B
		new Thread(new Runnable() {

			@Override
			public void run() {
				for (int i = 1; i < 100; i++) {
					synchronized (object) {
						System.out.println(Thread.currentThread().getName() + " " + (-1) * i);
						// 唤醒线程A
						object.notify();
						/*
						 * try { Thread.sleep(1); } catch (InterruptedException
						 * e) { // TODO Auto-generated catch block
						 * e.printStackTrace(); }
						 */

						/**
						 * 为什么不能放在这个位置:
						 * 因为静态代码块执行完毕,虽然等待了1毫秒,但是还不会释放锁(sleep()方法不会释放锁的),
						 * 只有等静态代码块执行完毕的时候才开始释放锁,释放完锁,线程A和线程B会去争夺锁不一定
						 * 是A获得到锁,所以不会出现 1 -1 2 -2 3 -3 ....的效果,所以将这段代码写在锁释放完后
						 * 面,让其失去机会获取锁,然A获取到锁,执行,然后等待,释放锁,等待B线程唤醒,B抢到锁执行
						 * 代码,唤醒A,这样交替执行
						 */
					}
					
					//线程A和线程B交换执行关键所在
					try {
						Thread.sleep(1);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

			}
		}, "B").start();
	}
}

结果为:

A 1
B -1
A 2
B -2
A 3
B -3
A 4
B -4
A 5
B -5
A 6
B -6
A 7
B -7
.......

你可能感兴趣的:(java基础)