Java 多线程 示例

版权声明:本文为博主原创文章,转载请注明出处 https://github.com/baiiu https://blog.csdn.net/u014099894/article/details/68546480

1. 死锁

private static class DeadLockRunnable implements Runnable {
    private final Object objA;
    private final Object objB;

    DeadLockRunnable(Object objA, Object objB) {
        this.objA = objA;
        this.objB = objB;
    }

    @Override
    public void run() {
        while (true) {
            // 同步嵌套
            synchronized (objA) {
                System.out.println(Thread.currentThread().getName() + " -->  " + objA);

                synchronized (objB) {
                    System.out.println(Thread.currentThread().getName() + " --> " + objB);
                }
            }
        }
    }
}

public static void main(String[] args) {
     Object objA = new Object();
     Object objB = new Object();

     //传入不同锁,被持有
     new Thread(new DeadLockRunnable(objA, objB)).start();
     new Thread(new DeadLockRunnable(objB, objA)).start();
}

2. 卖票问题

class SellingRunnable implements Runnable {
    private int ticket = 100; //volatile不能保证原子性,必须使用同步,synchronized或lock

    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if (ticket == 0) {
                    break;
                }

                System.out.println(Thread.currentThread().getName() + " --> " + ticket);

                --ticket; //这是一个非原子操作,不能放在第一句
            }
        }
    }
}

public static void main(String[] args) {
   Runnable runnable = new SellingRunnable();

   Thread thread1 = new Thread(runnable, "窗口1");
   Thread thread2 = new Thread(runnable, "窗口2");
   Thread thread3 = new Thread(runnable, "窗口3");

   thread1.start();
   thread2.start();
   thread3.start();
}

多生成者多消费者

/*
  * 资源类
  */
class Resource {
    private int count;
    private boolean flag;//生产好了么

    private Lock mLock = new ReentrantLock();
    /*
        一个锁上有多个监视器,不同的监视器监视不同的线程,控制不同的线程,但共享着一把锁,即线程没有持有锁便进不来
     */
    private Condition condition_con = mLock.newCondition();//控制消费者线程
    private Condition condition_pro = mLock.newCondition();//控制生产者线程

    void produce() {
        mLock.lock();
        try {
            while (flag) {
                //生产好了,等待消费
                condition_pro.await();
            }

            //生产
            ++count;
            System.out.println(Thread.currentThread().getName() + "生产--> " + count);
            flag = true;//生产好了,去消费吧
            condition_con.signal();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            mLock.unlock();
        }
    }

    void consume() {
        mLock.lock();
        try {
            while (!flag) {
                //没生产好,等待生产
                condition_con.await();
            }

            //生产好了,消费
            System.out.println(Thread.currentThread().getName() + "消费---> " + count);
            flag = false;//消费完了,去生产吧
            condition_pro.signal();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            mLock.unlock();
        }
    }
}

/*
  * 消费者
  */
class Consumer implements Runnable {
    Resource r;

    public Consumer(Resource r) {
        this.r = r;
    }

    @Override
    public void run() {
        while (true) {
            r.consume();
        }
    }
}

/*
  * 生产者
  */
class Producer implements Runnable {
    Resource r;

    public Producer(Resource r) {
        this.r = r;
    }

    @Override
    public void run() {
        while (true) {
            r.produce();
        }
    }
}

//测试类
public class TestLock {
    public static void main(String[] args) {
        Resource r = new Resource();

        Consumer consumer = new Consumer(r);
        Producer producer = new Producer(r);

        Thread t1 = new Thread(consumer);
        Thread t2 = new Thread(consumer);

        Thread t3 = new Thread(producer);
        Thread t4 = new Thread(producer);

        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

打印数字

线程1打印123、线程2打印456、线程1打印789。主要用于理解Condition:
一个锁上有多个监视器,不同的监视器监视不同的线程,控制不同的线程,但共享着一把锁,即线程没有持有锁便无法执行。

class PrintCount {
    private int count = 1;

    private Lock lock = new ReentrantLock();
    private Condition reachThreeCondition = lock.newCondition();//到3了么
    private Condition reachSixCondition = lock.newCondition();//到6了么

    void print123() {
        lock.lock();

        try {
            while (count <= 3) {
                System.out.println(Thread.currentThread().getName() + " --> " + count);
                ++count;
            }

            reachThreeCondition.signal();
        } finally {
            lock.unlock();
        }

        lock.lock();
        try {
//            while (count <= 6) {
            reachSixCondition.await();
//            }

            while (count <= 9) {
                System.out.println(Thread.currentThread().getName() + " --> " + count);
                ++count;
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }

//    void print789() {
//        lock.lock();
//
//        try {
////            while (count <= 6) {
//            reachSixCondition.await();
////            }
//
//            while (count <= 9) {
//                System.out.println(Thread.currentThread().getName() + " --> " + count);
//                ++count;
//            }
//
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        } finally {
//            lock.unlock();
//        }
//
//    }

    void print456() {
        lock.lock();

        try {
            while (count <= 3) {
                reachThreeCondition.await();
            }

            while (count <= 6) {
                System.out.println(Thread.currentThread().getName() + " --> " + count);
                ++count;
            }

            reachSixCondition.signal();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}


public class OneSample {

    public static void main(String[] args) {
        final PrintCount r = new PrintCount();

        new Thread() {
            @Override
            public void run() {
                r.print123();
//                r.print789();
            }
        }.start();

        new Thread() {
            @Override
            public void run() {
                r.print456();
            }
        }.start();

    }

}

猜你喜欢

转载自blog.csdn.net/u014099894/article/details/68546480