要求描述
兩個線程,其中一個線程打印奇數,另外一個線程打印偶數。兩個線程交替打印,輸入1,2,3,...,100
基本思路
利用通知等待機制,第一個線程打印後,然後喚醒第二個線程,並釋放鎖。第二個線程執行同樣的操作
代碼實現
package basicKnowledge.thread;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @基本功能:線程交替打印輸出奇偶
* @program:summary
* @author:peicc
* @create:2019-09-26 09:11:15
**/
public class ThreadPrint {
static Object object=new Object();
public static void main(String[] args) {
Thread thread1=new Thread(new Runnable() {
@Override
public void run() {
synchronized (object){
for (int i = 1; i <100 ; i+=2) {
System.out.println(Thread.currentThread().getName()+": "+i);
object.notify();//喚醒其他線程
try {
object.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
},"打印奇數線程");
Thread thread2=new Thread(new Runnable() {
@Override
public void run() {
synchronized (object){
for (int i = 2; i <=100 ; i+=2) {
System.out.println(Thread.currentThread().getName()+": "+i);
object.notify();//喚醒其他線程
try {
object.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
},"打印偶數線程");
thread1.start();
thread2.start();
}
}
輸出結果(後面的省略)
打印奇數線程: 1
打印偶數線程: 2
打印奇數線程: 3
打印偶數線程: 4
打印奇數線程: 5
打印偶數線程: 6
打印奇數線程: 7
打印偶數線程: 8
打印奇數線程: 9
打印偶數線程: 10
上述方法基本解決了我們的需求,但是有個問題,很嚴重,那就是打印結束後打印偶數的線程再次進入了等待狀態,整個程序無法終止。
代碼升級版
package leetcode;
/**
* @基本功能:兩個線程交替執行,一個輸出偶數,一個輸出奇數
* @program:summary
* @author:peicc
* @create:2019-07-29 12:56:49
**/
//線程執行完畢如何終止?
public class ThreadTurn {
static Object o=new Object();
static boolean flag=false;//標誌位
public static void main(String[] args) {
ThreadTurn threadTurn=new ThreadTurn();
Thread oddThread=new Thread(new Runnable() {
@Override
public void run() {
synchronized (threadTurn){
for (int i = 1; i <100 ; ) {
if(!flag){
System.out.println("打印奇數線程"+i);
threadTurn.notify();//喚醒等待線程
flag=true;
i+=2;
}else{
try {
threadTurn.wait();
// Thread.sleep(100);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
},"奇數線程");
Thread evenThread=new Thread(new Runnable() {
@Override
public void run() {
synchronized (threadTurn){
for (int i = 2; i <= 100; ) {
if(flag){
System.out.println("打印偶數線程"+i);
threadTurn.notify();//喚醒等待線程
flag=false;
i+=2;
}else{
try {
threadTurn.wait();
// Thread.sleep(100);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
},"偶數線程");
evenThread.start();
oddThread.start();
}
}
補充練習
兩個線程,其中一個線程打印數字,另外一個線程打印字母。兩個線程交替打印,輸入1,2,a,3,4,b,5,6,c
package basicKnowledge.thread;
/**
* @基本功能:兩個線程交替執行,一個輸出偶數,一個輸出奇數
* @program:summary
* @author:peicc
* @create:2019-07-29 12:56:49
**/
//線程執行完畢如何終止?
public class ThreadPrint2 {
static Object o=new Object();
static boolean flag=true;//標誌位
public static void main(String[] args) {
ThreadPrint2 threadTurn=new ThreadPrint2();
Thread oddThread=new Thread(new Runnable() {
@Override
public void run() {
synchronized (threadTurn){
int count=0;
for (int i = 1; i <=52 ; ) {
if(count<2){
System.out.println("打印數字線程"+i);
threadTurn.notify();//喚醒等待線程
count++;
i++;
}else{
try {
count=0;
threadTurn.wait();
// Thread.sleep(100);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
},"奇數線程");
Thread evenThread=new Thread(new Runnable() {
@Override
public void run() {
synchronized (threadTurn){
for (int i = 0; i <26; ) {
if(flag){
System.out.println("打印字母線程"+(char)(i+'a'));
threadTurn.notify();//喚醒等待線程
flag=false;
i++;
}else{
try {
flag=true;
threadTurn.wait();
// Thread.sleep(100);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
},"偶數線程");
oddThread.start();
evenThread.start();
}
}