[ターン]マルチスレッドの基礎 - マルチスレッド実行順序の典型的な例を制御する方法

交互に3回行うように1、サブスレッドの実行は、メインスレッド5つのラン、10回行います


public class Bussiness {
    private boolean subFlag = true;//主线程和子线程切换的控制开关
    public static void main(String[] args) {
        final Bussiness bussiness = new Bussiness();
        // 子线程
        new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < 3; i++) {
                    bussiness.subMethod();
                }
            }
        }).start();
        // 主线程
        for (int i = 0; i < 3; i++) {
            bussiness.mainMethod();
        }
    }
    public synchronized void mainMethod() {
        while (subFlag) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()
                    + " : main thread running loop count -- " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        subFlag = true;
        notify();
    }
    public synchronized void subMethod() {
        while (!subFlag) {
            try {
                wait();//在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (int i = 0; i < 10; i++) {
            System.err.println(Thread.currentThread().getName()
                    + " : sub thread running loop count -- " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        subFlag = false;
        notify();//唤醒在此对象监视器上等待的单个线程。
    }
}

2、100枚のチケットがあり、二つのウィンドウがあると同時に、チケットをつかむ、投票をつかむために、マルチスレッド・シミュレーション・エフェクトを使用してください

package threadLearning.threadSafeProblem;
/**
 *
 * @classDesc: 功能描述:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。
 * @author: zjb
 * @createTime: 创建时间:2018-6-23 下午11:12:29
 * @version: v1.0
 * @copyright:
 */
public class ThreadTrain1 implements Runnable {
    private static int count = 100;
    private static Object oj = new Object();

    public void run() {
        while (count > 0) {
            try {
                //Thread.sleep(1000);
            } catch (Exception e) {

            }
            sale();
        }

    }
    public  void sale() {
        // 前提 多线程进行使用、多个线程只能拿到一把锁。
        // 保证只能让一个线程 在执行 缺点效率降低
        /*如何解决线程同步问题:
          方法1:使用同步代码块,如下;
          方法2:使用同步函数:在方法上修饰synchronized 称为同步函数,如:
         public synchronized void sale()
            思考:同步函数使用this锁。证明方式: 一个线程使用同步代码块(this明锁),另一个线程使用同步函数。
        如果两个线程抢票不能实现同步,那么会出现数据错误。
         */
        synchronized (oj) {
            if (count > 0) {
                System.out.println(Thread.currentThread().getName() + ",出售第"
                        + (100 - count + 1) + "票");
                count--;
            }
        }

    }

}

package threadLearning.threadSafeProblem;
/**
 *
 * @classDesc: 功能描述:
 * @author: zjb
 * @createTime: 创建时间:2018-6-23 下午11:24:14
 * @version: v1.0
 * @copyright:
 */

public class ObtainTest1 {
    public static void main(String[] args) {
        ThreadTrain1 threadTrain = new ThreadTrain1();

        Thread obtainThread1 = new Thread(threadTrain, "1号窗口");
        Thread obtainThread2 = new Thread(threadTrain, "2号窗口");
        obtainThread1.start();
        obtainThread2.start();
    }

}

3、4秒の実行間隔一度タイマーを使用して、及び2つの第二間隔を行い、そう実行

タイマー:ツール、後にバックグラウンドスレッドで実行するようにスケジュールそのネジ付きタスクと。タスクを実行する、または定期的に繰り返すように配置することができ
、コンストラクタ:
タイマー(文字列名)は
、その関連するスレッド指定された名前を持つ新しいタイマーを作成します。
タイマー(文字列名、ブールisDaemon)は、
その関連するスレッド指定された名前を持つ新しいタイマーを作成し、あなたは、デーモンとして実行するように指定することができます。
方法:
空のスケジュール(TimerTaskをタスク、長い遅延)
スケジュール指定したタスク指定した遅延時間の経過後

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimerTastCus extends TimerTask {
    private static volatile int count = 1;//确保每个执行器获取到的count值都是最新的
    
    @Override
    public void run() {
//实现一个值在0和1之前交替取值,进而使得执行器4秒,2秒交替执行
        count = (count + 1) % 2;
        System.err.println("count---》 "+count);
        System.out.println("当前执行线程为-创建对象前->"+Thread.currentThread().getName());
        new Timer().schedule(new TimerTastCus(), 2000+2000*count);
        
    }

    public static void main(String args[]) {
        Timer timer = new Timer();
        timer.schedule(new TimerTastCus(), 2000 + 2000 * count);//毫秒
        while (true) {
            try {
                System.out.println("当前执行线程为-->"+Thread.currentThread().getName()+"   当前时间的秒数:-->"+new Date().getSeconds());
                Thread.sleep(1000);//
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

転載元:https://www.cnblogs.com/jiarui-zjb/p/9622562.html

おすすめ

転載: blog.csdn.net/linmengmeng_1314/article/details/88090898