zoukankan      html  css  js  c++  java
  • 信号量在多线程通讯运用

    同步的三个方法:

       必须在同步块 或者同步方法中使用

    1. notify()  停止访问当前线程,转去执行挂起的线程
    2. notifyALL()
    3. wait() 挂起 释放对线程资源的访问  如果有参数时间 那么再等待特定的时间再挂起
    class CommonTalkVar{
          private char product;
          /**同步信号量
           *  true: 持有产品状态
           *  false: 已经消费产品状态
           * */
          private  boolean isProduced=false;
    
        /**
         * @description production method
         */
        public synchronized void putCommonData(char product){
                if(isProduced){
                    try {
                        System.out.println(Thread.currentThread().getName()+"消费者还没有消费产品");
                        wait();
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
                this.product=product;
                this.isProduced=true;
                System.out.println(Thread.currentThread().getName()+"生产者生产:"+this.product);
                notify();
        }
        /**
         * @description consumer method
         */
        public synchronized char getCommonData(){
            if(!isProduced){
                try {
                    System.out.println(Thread.currentThread().getName()+"生产者还没有生产产品");
                    wait();
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
            this.isProduced=false;
            System.out.println(Thread.currentThread().getName()+"消费者消费:"+this.product);
            notify();
            return this.product;
        }
    }
    
    class Consumer extends Thread{
        private CommonTalkVar commonTalkVar;
    
        public Consumer(CommonTalkVar commonTalkVar){
            this.commonTalkVar=commonTalkVar;
        }
    
        @Override
        public  void run() {
            char tempc;
            do{
                try {
                    Thread.sleep((int)(Math.random()*3000));
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                tempc=commonTalkVar.getCommonData();
            }while (tempc!='D');
        }
    }
    
    class Product extends Thread{
        private CommonTalkVar commonTalkVar;
        public Product(CommonTalkVar commonTalkVar){
            this.commonTalkVar=commonTalkVar;
        }
    
        @Override
        public  void run() {
            for (char i = 'A'; i <= 'D'; i++){
                try {
                    Thread.sleep((int)(Math.random()*3000));
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                commonTalkVar.putCommonData(i);
            }
        }
    }
    
    public class ConsumerAndProduct {
        public static void main(String[] args) {
            CommonTalkVar talkVar = new CommonTalkVar();
    
            new Consumer(talkVar).start();
            new Product(talkVar).start();
        }
    }

    多线程的的顺序控制

    实际上就是注意 notifyALL() 方法的控制用法

    package Thread;
    
    public class Demo1_Synchronized {
    
        /**
         * @param args
         * 同步代码块
         */
        public static void main(String[] args) {
            final Printer p = new Printer();
            
            new Thread() {
                public void run() {
                    while(true) {
                        try {
                            p.print1();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
            
            new Thread() {
                public void run() {
                    while(true) {
                        try {
                            p.print2();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
            
            new Thread() {
                public void run() {
                    while(true) {
                        try {
                            p.print3();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        }
    
    }
    
    class Printer {
        Demo d = new Demo();
    
        private static volatile int signal=1;
        
        public void print1() throws InterruptedException {
            synchronized (this) {
                while(this.signal!=1) {
                    this.wait();
                }
                this.signal=2;
                System.out.println("11111");
                this.notifyAll();
            }
        }
    
        public void print2() throws InterruptedException {
            synchronized (this) {
                while(this.signal!=2) {
                    this.wait();
                }
                this.signal=3;
                System.out.println("22222");
                this.notifyAll();
            }
        }
        
        public void print3() throws InterruptedException {
            synchronized (this) {
                while(this.signal!=3) {
                    this.wait();
                }
                this.signal=1;
                System.out.println("33333");
                this.notifyAll();
            }
        }
    }
    
    //定义的锁类
    class Demo {
    }

    锁的同步

    package Thread;
    
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Test6 {
    
        public static void main(String[] args) {
            new Ticket12().start();
            new Ticket12().start();
            new Ticket12().start();
            new Ticket12().start();
        }
    
    }
    class Ticket12 extends Thread {
        private static volatile int ticket = 100;
        
        private static final ReentrantLock lock=new ReentrantLock();
        public void  run() {
            while (true) {
                    lock.lock();
                    try {
                        if (ticket <= 0) {
                            break;
                        }
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(getName() + "这是第" + ticket-- + "号票");
                        
                    } finally {
                        lock.unlock();
                    }
            }
        }
    }

    可重入锁的用法

    package Thread;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Demo1_ReentrantLock {
        public static void main(String[] args) {
            final PrinterReentrantLock p = new PrinterReentrantLock();
            
            new Thread() {
                public void run() {
                    while(true) {
                        try {
                            p.print1();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
            
            new Thread() {
                public void run() {
                    while(true) {
                        try {
                            p.print2();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
            
            new Thread() {
                public void run() {
                    while(true) {
                        try {
                            p.print3();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        }
    
    }
    
    class PrinterReentrantLock {
        
        private int signal=1;
        
        private static final ReentrantLock lock=new ReentrantLock();
        
        private static final Condition c1=lock.newCondition();
        private static final Condition c2=lock.newCondition();
        private static final Condition c3=lock.newCondition();
    
        public void print1() throws InterruptedException {
                lock.lock();
                try {
                    while (this.signal != 1) {
                        c1.await();
                    }
                    this.signal = 2;
                    System.out.println("11111");
                    c2.signal();
                } finally {
                    lock.unlock();
                }
        }
    
        public void print2() throws InterruptedException {
                lock.lock();
                try {
                    while (this.signal != 2) {
                        c2.await();
                    }
                    this.signal = 3;
                    System.out.println("22222");
                    c3.signal();
                } finally {
                    lock.unlock();
                }
        }
        
        public void print3() throws InterruptedException {
                lock.lock();
                try {
                    while (this.signal != 3) {
                        c3.await();
                    }
                    this.signal = 1;
                    System.out.println("33333");
                    c1.signal();
                } finally {
                    lock.unlock();
                }
        }
    }
  • 相关阅读:
    Qt QSqlquery结果集使用——size()函数无法返回结果集个数
    Bootstrap 响应式珊格布局
    Bootstrap navbar使用
    UML 类图之间关系
    QMessageBox 主要用法
    QT QString 与 int 转化
    Qt 连接数据库失败 QSqlDatabase: QMYSQL driver not loaded
    数据库使用问题 mysqld.sock找不到
    操作系统(二)--操作系统概述
    操作系统(一)--计算机系统概述
  • 原文地址:https://www.cnblogs.com/dgwblog/p/11681511.html
Copyright © 2011-2022 走看看