题外话
今天终于周末了,没有出去运动,最近学了多线程,想练习下,找了到练习题,多线程交替打印1到100的奇偶数。
思路
首先在多线程环境下想保证交替打印,必须得有wait和notify的等待唤醒机制来控制,而wait和notify必须在持有锁的情况下,才可以使用,所以我想到了synchronized,而synchronized可以修饰方法或者synchronized同步块都可以实现。synchronized修饰方法实际上是使用当前使用对象的锁,而synchronized同步块既可以锁住当前对象,任意对象,类都可以的,我根据思路写了几种实现。
实现1:synchronized方法锁
public class MyTask {
public synchronized void printNumber(int i) {
try {
this.notify();
System.out.println(Thread.currentThread().getName() + " " + i);
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class SwapPrint {
public static void main(String[] args) {
final MyTask myTask = new MyTask();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1 ; i <= 10 ; i+=2) {
myTask.printNumber(i);
}
}
});
t1.setName("Thread t1");
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 2 ; i <= 10 ; i+=2) {
myTask.printNumber(i);
}
}
});
t2.setName("Thread t2");
t2.start();
}
}
1.jpg
实现2:synchronized(this)对象锁
这种实现和实现1没什么区别,实现1虽然是synchronized修饰方法的方式,实际上还是使用当前对象的锁。
public class MyTask {
public void printNumber(int i) {
try {
synchronized (this) {
this.notify();
System.out.println(Thread.currentThread().getName() + " " + i);
this.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class SwapPrint {
public static void main(String[] args) {
final MyTask myTask = new MyTask();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1 ; i <= 10 ; i+=2) {
myTask.printNumber(i);
}
}
});
t1.setName("Thread t1");
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 2 ; i <= 10 ; i+=2) {
myTask.printNumber(i);
}
}
});
t2.setName("Thread t2");
t2.start();
}
}
实现3:等待队列Condition实现
public class MyTask {
private ReentrantLock rl = new ReentrantLock();
private Condition condition = rl.newCondition();
public void printNumber(int i) {
try {
rl.lock();
condition.signal();
System.out.println(Thread.currentThread().getName() + " " + i);
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rl.unlock();
}
}
}
public class SwapPrint {
public static void main(String[] args) {
final MyTask myTask = new MyTask();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1 ; i <= 10 ; i+=2) {
myTask.printNumber(i);
}
}
});
t1.setName("Thread t1");
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 2 ; i <= 10 ; i+=2) {
myTask.printNumber(i);
}
}
});
t2.setName("Thread t2");
t2.start();
}
}
网友评论