n个线程按顺序输出1到100的三种方法
代码均用java实现,经测试无误。
方法一
在循环中中判断是否该自己输出了,是的话就输出,不是的话就进入下一个循环,当即将输出的数字超过100,循环结束。
用synchronize加锁保证cnt++的原子性
public class Test4 extends Thread {
static int n = 6; // 线程数量
static volatile int cnt = 0; // 计数,到100结束
private int id; // 线程编号
public Test4(int id) {
this.id = id;
}
@Override
public void run() {
while (cnt <= 100) {
if (cnt % n == id) {
synchronized (Test4.class) {
cnt++;
if(cnt > 100){
break;
}
System.out.println("thread_" + id + " cnt:" + cnt);
}
}
}
}
public static void main(String[] args) {
for(int i = 0; i < n; i++){
new Test4(i).start();
}
}
}
方法二
用等待唤醒机制,当一个线程执行完当前任务后再唤醒其他线程来执行任务,自己去休眠,避免在线程执行任务的时候其他线程处于忙等状态,浪费cpu资源。
package multiThread;
public class Test4 extends Thread {
static int n = 6; // 线程数量
static volatile int cnt = 0; // 计数,到100结束
private int id; // 线程编号
public Test4(int id) {
this.id = id;
}
@Override
public void run() {
while (cnt <= 100) {
synchronized (Test4.class) {
if (cnt % n == id){
cnt++;
if(cnt > 100){
Test4.class.notify();
break;
}
System.out.println("thread_" + id + " cnt:" + cnt);
Test4.class.notify();
try {
Test4.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
for(int i = 0; i < n; i++){
new Test4(i).start();
}
}
}
方法三
用 ReentrantLock 来解决,本质和解法二一样,不过是用synchronized 换成 lock 来实现,等待唤醒机制用 signal 和 await来实现
package multiThread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test4 extends Thread {
static Lock lock = new ReentrantLock();
static Condition condition = lock.newCondition();
static int n = 6; // 线程数量
static volatile int cnt = 0; // 计数,到100结束
private int id; // 线程编号
public Test4(int id) {
this.id = id;
}
@Override
public void run() {
while (cnt <= 100) {
lock.lock();
while (cnt % n == id){
cnt++;
if(cnt > 100){
condition.signalAll();
break;
}
System.out.println("thread_" + id + " cnt:" + cnt);
condition.signal();
try {
condition.await();
if(cnt > 100){
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.unlock();
}
}
public static void main(String[] args) {
for(int i = 0; i < n; i++){
new Test4(i).start();
}
}
}