Java案例:两个线程交替执行

Java案例:两个线程交替执行_第1张图片


任务1、两个线程,一个打印A到Z,一个打印1到26,交替执行。

package net.hw.test.thread;

/**
 * 两个线程,一个打印A到Z,一个打印1到26,交替执行
 *
 * Created by howard on 2018/1/18.
 */
public class AlternateThreads {
    public static void main(String[] args) {
        Res res = new Res();

        Thread letterThread = new Thread(new LetterRunner(res));
        Thread numberThread = new Thread(new NumberRunner(res));

        letterThread.start();
        numberThread.start();

    }
}

class Res {
    char letter = 'A';
    int number = 1;
    boolean isLetter = true;
}

class LetterRunner implements Runnable {
    Res res;

    public LetterRunner(Res res) {
        this.res = res;
    }

    @Override
    public void run() {
        while (res.letter <= 'Z') {
            synchronized (res) {
                if (!res.isLetter) {
                    try {
                        res.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.out.print(res.letter);
                    res.letter++;
                    res.isLetter = false;
                    res.notify();
                }
            }
        }
    }
}

class NumberRunner implements Runnable {
    Res res;

    public NumberRunner(Res res) {
        this.res = res;
    }

    @Override
    public void run() {
        while (res.number <= 26) {
            synchronized (res) {
                if (res.isLetter) {
                    try {
                        res.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.out.print(res.number + " ");
                    res.number++;
                    res.isLetter = true;
                    res.notify();
                }
            }
        }
    }
}
运行结果如下:

任务2、两个线程,一个打印100内的奇数,一个打印100内的偶数,交替执行

package net.hw.test.thread;

/**
 * 两个线程,一个打印100内的奇数,一个打印100内的偶数,交替执行
 * 
 * Created by howard on 2018/1/18.
 */
public class AlternateThreads01 {

    public static void main(String[] args) {
        Num num = new Num();

        Thread oddThread = new Thread(new PrintOddNum(num));
        Thread evenThread = new Thread(new PrintEvenNum(num));

        oddThread.start();
        evenThread.start();
    }
}


/**
 * 要打印的资源
 */
class Num {
    int i = 1;
    boolean flag = false;
}

/**
 * 打印奇数的线程
 */
class PrintOddNum implements Runnable {
    Num num;

    public PrintOddNum(Num num) {
        this.num = num;
    }

    @Override
    public void run() {
        while (num.i < 100) {
            synchronized (num) {
                if (num.flag) {
                    try {
                        num.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.out.println("奇数线程:" + num.i);
                    num.i++;
                    num.flag = true;
                    num.notify();
                }
            }
        }
    }
}

/**
 * 打印奇数的线程
 */
class PrintEvenNum implements Runnable {
    Num num;

    public PrintEvenNum(Num num) {
        this.num = num;
    }

    @Override
    public void run() {
        while (num.i < 100) {
            synchronized (num) {
                if (!num.flag) {
                    try {
                        num.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.out.println("偶数线程:" + num.i);
                    num.i++;
                    num.flag = false;
                    num.notify();
                }
            }
        }
    }
}
运行结果如下:

Java案例:两个线程交替执行_第2张图片

任务3、两个线程,一个线程逐行读文件,一个线程逐行输出,交替执行
package net.hw.test.thread;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * 两个线程,一个线程逐行读文件,一个线程逐行输出,交替执行
 *
 * Created by howard on 2018/1/18.
 */
public class AlternateThreads02 {
    public static void main(String[] args) throws Exception {
        Resource resource = new Resource();

        Thread readingThread = new Thread(new ReadingRunner(resource));
        Thread printingThread = new Thread(new PrintingRunner(resource));

        readingThread.start();
        printingThread.start();
    }
}

class Resource {
    String nextLine = null;
    BufferedReader br = new BufferedReader(new FileReader("love.txt"));

    boolean isReading = true;

    Resource() throws IOException {
        nextLine = br.readLine();
    }
}

class ReadingRunner implements Runnable {
    private Resource resource;

    public ReadingRunner(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        try {
            while (resource.nextLine != null) {
                synchronized (resource) {
                    if (!resource.isReading) {
                        resource.wait();
                    } else {
                        System.out.print("执行读线程->");
                        resource.isReading = false;
                        resource.notify();
                    }
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class PrintingRunner implements Runnable {
    private Resource resource;

    public PrintingRunner(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        try {
            while (resource.nextLine != null) {
                synchronized (resource) {
                    if (resource.isReading) {
                        resource.wait();
                    } else {
                        System.out.println("执行打印线程:" + resource.nextLine);
                        resource.isReading = true;
                        resource.nextLine = resource.br.readLine();
                        resource.notify();
                    }
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
运行结果如下:

Java案例:两个线程交替执行_第3张图片

任务4、一个线程打印A~Z,一个线程打印1~52的数据。实现交替打印,输出结果为12A 34B 56C...........4950Y 5152Z。

Java案例:两个线程交替执行_第4张图片

package net.hw.test.thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by howard on 2018/1/18.
 */
public class AlternateThreads03 {

    public static void main(String[] args) {
        final Data data = new Data();

        Thread letterThread = new Thread(new LetterPrintRunner(data));
        Thread numberThread = new Thread(new NumberPrintRunner(data));

        letterThread.start();
        numberThread.start();
    }
}


class Data {
    int number = 1;
    char letter = 'A';
    boolean isLetter = false;
    Lock lock = new ReentrantLock();
    Condition condLetter = lock.newCondition();
    Condition condNumber = lock.newCondition();

    public void printLetter() {
        lock.lock();
        try {
            if (!isLetter) {
                condLetter.await();
            } else {
                System.out.print(letter + " ");
                letter++;
                Thread.sleep(100);
                isLetter = false;
                condNumber.signal();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
           lock.unlock();
        }
    }

    public void printNumber() {
        lock.lock();
        try {
            if (isLetter) {
                condNumber.await();
            } else {
                System.out.print(number);
                number++;
                System.out.print(number);
                number++;
                Thread.sleep(100);
                isLetter = true;
                condLetter.signal();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

/**
 * 字母打印线程
 */
class LetterPrintRunner implements Runnable {
    private Data data;

    public LetterPrintRunner(Data data) {
        this.data = data;
    }

    @Override
    public void run() {
        while (data.letter <= 'Z') {
            data.printLetter();
        }
    }
}

/**
 * 数字打印线程
 */
class NumberPrintRunner implements Runnable {
    private Data data;

    public NumberPrintRunner(Data data) {
        this.data = data;
    }

    @Override
    public void run() {
        while (data.number <= 52) {
            data.printNumber();
        }
    }
}
运行结果如下:

任务5、使用多线程模拟多线程装弹及射出过程
(1)开启3个线程装弹,开启2个线程发射子弹
(2)弹夹最多只能够装载12颗子弹
(3)一次只能够发射一枚子弹,发射子弹的时候不能进行装弹,在装弹的时候不能进行发射。
(4)整个过程就是“装载”、“发射”、“装载”、“发射”、“装载”、“发射”

Java案例:两个线程交替执行_第5张图片

package net.hw.test.thread;

/**
 * Created by howard on 2018/1/18.
 */

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 使用多线程模拟多线程装弹及射出过程
 *
 * 1. 开启3个线程装弹,开启2个线程发射子弹
 * 2. 弹夹最多只能够装载12颗子弹
 * 3. 一次只能够发射一枚子弹,发射子弹的时候不能进行装弹,在装弹的时候不能进行发射。
 * 4. 整个过程就是“装载”、“发射”、“装载”、“发射”、“装载”、“发射”
 */
public class LoadShootBullet {

    public static void main(String[] args) {

        final BulletManager manager = new BulletManager();

        // 开启3个线程装弹
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        manager.load();
                    }
                }
            }).start();
        }

        // 开启两个线程发射
        for (int i = 0; i < 2; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        manager.shoot();
                    }

                }
            }).start();
        }

    }

    /**
     * 子弹管理类
     */
    static class BulletManager {
        int count = 1;
        boolean isShoot = false;
        ArrayBlockingQueue blocking = new ArrayBlockingQueue(12);
        Lock lock = new ReentrantLock();
        Condition condShoot = lock.newCondition();
        Condition condLoad = lock.newCondition();

        /**
         * 发射
         */
        public void shoot() {
            lock.lock();
            try {
                if (!isShoot) {
                    condShoot.await();
                }
                if (blocking.size() == 0) {
                    isShoot = false;
                    condLoad.signal();
                } else {
                    Integer i = blocking.take();
                    System.out.println("发射第" + i + "个子弹!");
                    blocking.remove(i);
                    Thread.sleep(100);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

        }

        /**
         * 装载
         */
        public void load() {
            lock.lock();
            try {
                if (isShoot) {
                    condLoad.await();
                }
                if (blocking.size() == 12) {
                    isShoot = true;
                    condShoot.signal();
                } else {
                    blocking.put(count);
                    System.err.println("装载第" + count + "个子弹!");
                    Thread.sleep(100);
                    count++;
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
}
运行结果如下:
Java案例:两个线程交替执行_第6张图片

你可能感兴趣的:(Java编程)