zoukankan      html  css  js  c++  java
  • 线程之交替执行的实例

     

    4.java多线程交替打印A和B?

    3.java多线程 更优雅的实现线程同步:交替打印A、B LockSupport实现

    2.Java实现两个线程交替打印问题

    1.A、B两个线程交替打印1 -- 100

    ====

    4.java多线程交替打印A和B?

    关键就是打印A和B的方法,synchronized的对象是同一个,即持有的锁是同一个,都是print这个类的实例
    然后又一个标志,当不是自己的时候,就释放自己的锁,并让线程进入等待状态,就是this.wait()
    当while执行完后,说明到自己的回合,打印字符,设置标志,然后唤醒锁为this的线程。

    class Print{
    boolean nowA=true;
    synchronized void printA(){
    while(!nowA){
    try {
    this.wait();
    } catch (Exception e) {
    }
    }
    nowA=false;
    System.out.println(Thread.currentThread()+" "+"A");
    this.notify();
    }

    synchronized void printB(){
    while(nowA){
    try {
    this.wait();
    } catch (Exception e) {
    }
    }
    nowA=true;
    System.out.println(Thread.currentThread()+" "+"B");
    this.notify();
    }

    }

    public class Test3 {

    public static void main(String[] args){
    Print print=new Print();
    new Thread(new Runnable() {
    @Override
    public void run() {
    for(int i=0;i<10;i++){
    print.printA();
    }

    }
    }).start();

    new Thread(new Runnable() {
    @Override
    public void run() {
    for(int i=0;i<10;i++){
    print.printB();
    }

    }
    }).start();;
    }

    }

    3.java多线程 更优雅的实现线程同步:交替打印A、B LockSupport实现

    一 问题概述
    线程或者进程之间有两种关系 同步和互斥,我们通常实现同步方法是使用线程的等待唤醒机制,而等待唤醒机制的使用是建立在互斥的继承上的。
    但是同步线程并不一定是必须要实现互斥的。比如一个线程打印A,一个线程打印B。这两个线程就没有互斥关系,但是提出这么个需求:交替打印A、B 。
    我们一般的解决方案,往往要使用wait()/notify机制。

    二 LockSupport 介绍
    LockSupport作为一个工具类,主要学习它的方法。
    park():在线程内调用,表示当前线程自我阻塞,直到获得许可证
    park(线程变量):让指定的线程获得许可证。
    一看这两个方法的定义,显然可以利用这两个方法实现线程的顺序调用(同步)


    三 两种思路实现交替打印A/B
    等待唤醒机制:

    /**
    * @program: test
    * @description: 交替打印A/B 等待唤醒机制
    * @author:
    * @create: 2019-07-22 14:28
    */
    public class Test3 {
    static class MyRun implements Runnable {
    static int i = 0;
    @Override
    public synchronized void run() {
    for (int j = 0; j < 10; j++) {
    if(i%2==0)
    System.out.println(Thread.currentThread().getName()+":A");
    else
    System.out.println(Thread.currentThread().getName()+":B");
    i++;
    this.notifyAll();
    try {
    if(i>=19)
    Thread.sleep(10);
    else
    this.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }

    public static void main(String[] args) {
    MyRun myRun = new MyRun();
    Thread a = new Thread(myRun);
    Thread b = new Thread(myRun);
    a.start();
    b.start();
    }
    }
      

    java.util.concurrent.locks.LockSupport 实现

    /**
    * @program: test
    * @description:交替打印A,B LockSupport实现
    * @author:
    * @create: 2019-07-22 14:03
    */
    public class Test2 {
    static Thread a=null;
    static Thread b=null;
    public static void main(String[] args) {
    a= new Thread(new Runnable() {
    @Override
    public void run() {

    for (int i = 0; i < 10; i++) {
    LockSupport.park();
    System.out.println(Thread.currentThread().getName()+":B");
    LockSupport.unpark(b);
    }
    }
    });
    b=new Thread((new Runnable() {
    @Override
    public void run() {
    for (int i = 0; i < 10; i++) {
    System.out.println(Thread.currentThread().getName()+":A");
    LockSupport.unpark(a);
    LockSupport.park();
    }
    }
    }));
    a.start();
    b.start();

    }
    }

    2.Java实现两个线程交替打印问题
    线程1负责打印a,b,c,d
    线程2负责打印1,2,3,4;要求控制台中输出的内容为 a1b2c3d4

    public class TestMain {
    static final Object object = new Object();

    public static void main(String[] args) throws InterruptedException {

    new Thread(new Runnable() {
    String a[] = {"a","b","c","d"};
    @Override
    public void run() {
    for(int i=0;i< 4 ;i++){
    synchronized (object){
    System.out.println("线程a 开始执行");
    object.notify();
    try {
    System.out.println("线程a 开始等待");
    object.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("线程a 继续执行");
    System.out.println(a[i]);
    System.out.println("线程a 执行结束");
    object.notify();
    }
    }
    }
    }).start();


    new Thread(new Runnable() {
    int a[] = {1,2,3,4};
    @Override
    public void run() {
    for(int i=0;i<4;i++){
    synchronized (object){
    System.out.println("线程1 开始执行");
    object.notify();
    try {
    System.out.println("线程1 开始等待");
    object.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("线程1 继续执行");
    System.out.println(a[i]);
    System.out.println("线程1 执行结束");
    }
    }

    }
    }).start();
    }
    }
    方案一:
    public class Test100_02 {
    private static Object object = new Object();
    private static boolean isFlag = false;
    public static void main(String[] args) {
    Thread t1 = new Thread(() -> {
    for (int i = 1; i <= 999; i+=2) {
    synchronized (object) {
    if (!isFlag) {
    System.out.println("current:" + i);
    isFlag = true;
    try {
    object.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    object.notify();
    }
    }
    }
    });

    Thread t2 = new Thread(() -> {
    for (int i = 2; i <= 1000; i+=2) {
    synchronized (object) {
    if (isFlag) {
    isFlag = false;
    System.out.println("current:" + i);
    object.notify();

    try {
    object.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    });

    t1.setPriority(Thread.MAX_PRIORITY);
    t1.start();
    t2.start();
    }
    }
    方案二:
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;

    public class Test100_01 {

    private static Lock lock = new ReentrantLock();
    private static Condition condition1 = lock.newCondition();
    private static Condition condition2 = lock.newCondition();

    public static void main(String[] args) {

    // thread 1
    Thread t1 = new Thread(() -> {
    for (int i = 1; i <= 999; i += 2) {
    lock.lock();
    try {
    System.out.println("current:" + i);
    condition1.await();
    condition2.signal();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    lock.unlock();
    }
    });

    // thread 2
    Thread t2 = new Thread(() -> {
    for (int i = 2; i <= 1000; i += 2) {
    lock.lock();
    try {
    System.out.println("current:" + i);
    condition1.signal();
    condition2.await();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    lock.unlock();

    }
    });

    t1.setPriority(Thread.MAX_PRIORITY);
    t1.start();
    t2.start();
    }
    }
    你的代码我运行了貌似会在中途卡住,
    我改进了一下顺序
    condition2.signal();
    System.out.println("current:" + i);
    condition1.await();

    condition1.signal();
    System.out.println("current:" + i);
    condition2.await();


  • 相关阅读:
    Hibernate框架简介
    [leecode]Evaluate Reverse Polish Notation
    linux 服务器之间配置免密登录
    大数据学习系列之一 ----- Hadoop环境搭建(单机)
    Hadoop hbase集群断电数据块被破坏无法启动
    CentOS 6 上安装 pip、setuptools
    CentOs6.7 python2.6升级到2.7.11
    安装phantomjs(Ubuntu版本 MacOS版本)
    Linux/Centos下安装部署phantomjs 及使用
    linux 查看系统磁盘、内存大小
  • 原文地址:https://www.cnblogs.com/awkflf11/p/12609843.html
Copyright © 2011-2022 走看看