Fork me on Gitee

信号量在多线程通讯运用

同步的三个方法:

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

  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();
            }
    }
}

 

posted @ 2019-10-15 22:17  ---dgw博客  阅读(360)  评论(0编辑  收藏  举报