直接上题:
要求创建三个线程,输出1-90, 最开始第一个线程输出1-5,第二个输出6-15,第三个输出16-30
接着再第一个线程输出31-35, 再第二个36-45,再第三个46-60...就这样循环下去,直到打印出90个数。
与互联网其他解决输出 1~75有差异,并且有些是错误,线程不安全的,这里进行常规方法改进。
jdk版本提升7,8后,synchronized大幅得以提升。
解决办法:通俗处理方式,简单易理解,使用共享对象,使用标志位转移线程状态,比较灵活。
package com.dennis.study.thread;
/**
* 要求创建三个线程,输出1-90, 最开始第一个线程输出1-5,第二个输出6-15,第三个输出16-30
* 接着再第一个线程输出31-35, 再第二个36-45,再第三个46-60...就这样循环下去,直到打印出90个数
* 解决办法:通俗处理方式,简单易理解,使用共享对象,使用标志位转移线程状态,比较灵活。
*
* @author dennis
*
*/
public class Thread3_1to90 {
static ShareData3_ sd = new ShareData3_(1);
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
sd.print1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
sd.print2();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
sd.print3();
}
}).start();
while (Thread.activeCount() > 0) {
Thread.currentThread().setDaemon(true);
}
}
}
class ShareData3_ {
private static int num = 0;
private volatile int flag = 1;
private final static int end = 90;
public ShareData3_( int f) {
this.flag = f;
}
/**
* 1~5 31~35,61~65,
*/
public synchronized void print1() {
while(num < end) {
while(flag > 1) {
wait_();
}
while (num % 30 < 5 && num < end) {
for (int i = 0; i < 5; i++) {
System.out.println("print1 = " + Thread.currentThread().getName() + "\t" + ++num);
}
}
sleep_();
flag = 2;
notifyAll();
}
}
/**
* 6~15 36~45,66~75,
*/
public synchronized void print2() {
while(num <end) {
while(flag != 2) {
wait_();
}
while (num % 30 < 15 && num % 30 > 4 && num < end) {
for (int i = 0; i < 10; i++) {
System.out.println("print2 = " + Thread.currentThread().getName() + "\t" + ++num);
}
}
sleep_();
flag = 3;
notifyAll();
}
}
/**
* 16~30 46~60,76~90,
*/
public synchronized void print3() {
while(num < end) {
while(flag < 3) {
wait_();
}
while (num % 30 > 14 && num < end) {
for (int i = 0; i < 15; i++) {
System.out.println("print3 = " + Thread.currentThread().getName() + "\t" + ++num);
}
}
sleep_();
flag = 1;
notifyAll();
}
}
private final void sleep_() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private final void wait_() {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
记录使用 ^_^