题目:使用多线程实现输出的效果为: 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
.......
推荐阅读
- Integer常量池结合源码解析
- Java基础|Java 打印空心等腰三角形(方法2)
- gradle 每次运行都会下载依赖的解决办法
- 使用vector代替数组
- 如何获取ResultSet的行数和列数
- Java 时间戳格式化
- Java基础|Android开发——JVM、Dalvik以及ART的区别
- XML|XML报文转Map
- Java 8 时间,字符串和Long时间戳互转
- JAVA基础|JAVA基础(TreeMap键是Student值是String案例)