线程通讯

1、代码实现多线程模拟3个窗口卖票

资源类:票

1-1

多线程:窗口

1-2

总结:各个窗口卖票,互相之间不沟通,谁先抢到了归谁。

2、有两个线程,可以操作初始值为一零的变量,实现一个线程对该变量加1,一个线程对该变量减1,实现交替,来10轮,最后变量初始值为0。

解题:   线程                操作(判断 干活 通知)                         资源

2-1

线程如下:

2-2

3、如果有两个线程加1,两个线程做减1呢?

public class ThreadWaitNotifyDemo3 {

    public static void main(String[] args) {

        Resource3 rs =new Resource3();

        new Thread(() -> {

            for (int i =0; i <10; i++)rs.add();

        },"A").start();

        new Thread(() -> {

            for (int i =0; i <10; i++)rs.add();

        },"B").start();

        new Thread(() -> {

            for (int i =0; i <10; i++)rs.sub();

        },"C").start();

        new Thread(() -> {

            for (int i =0; i <10; i++)rs.sub();

         },"D").start();

    }

}

class Resource3 {

    private int num =0;

    //操作共享资源加锁

    private Locklock =new ReentrantLock();

    private Conditioncondition =lock.newCondition();

    public void add() {

        lock.lock();

        try {

            while (num !=0) {

                condition.await();

            }

        num++;

        System.out.println(Thread.currentThread().getName() +":" +num);

        condition.signalAll();

    }catch (Exception e) {

        e.printStackTrace();

    }finally {

    lock.unlock();

    }

}

public void sub() {

    lock.lock();

    try {

        while (num ==0) {

        condition.await();

    }

     num--;

       System.out.println(Thread.currentThread().getName() +":" +num);

        condition.signalAll();

    }catch (Exception e) {

e.printStackTrace();

    }finally {

    lock.unlock();

    }

}

}

总结:1、对于资源,要封装为资源类,并把操作资源的方式封装在资源类中。

           2、操作共享资源加锁,ReentrantLock比synchrpnized效率要好。

           3、多个线程时要用notifyAll唤醒,否则可能会卡死。

           4、用while判断防止虚假唤醒。

你可能感兴趣的:(线程通讯)