实现两个线程交替执行

题目:使用多线程实现输出的效果为: 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 .......

    推荐阅读