• java 多线程安全问题的解决方法


    三种方法:

    同步代码块:

    synchronized(obj)

    {

           //obj表示同步监视器,是同一个同步对象

           /**.....

                  TODO SOMETHING

           */

    }

     

    同步方法

    格式:

    在方法上加上synchronized修饰符即可。(一般不直接在run方法上加!)

    synchronized 返回值类型 方法名(参数列表)

    {

           /**.....

                  TODO SOMETHING

           */

    }

    同步方法的同步监听器其实的是 this

    静态方法的同步

    同步方法

    同步代码块

    static不能和 this连用

    静态方法的默认同步锁是当前方法所在类的.class对象

    同步锁

    jkd1.5后的另一种同步机制:

    通过显示定义同步锁对象来实现同步,这种机制,同步锁应该使用Lock对象充当。

    在实现线程安全控制中,通常使用ReentrantLock(可重入锁)。使用该对象可以显示地加锁和解锁。

    具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

    public class X {

           private final ReentrantLock lock = new ReentrantLock();

           //定义需要保证线程安全的方法

           public void  m(){

                  //加锁

                  lock.lock();

                  try{

                         //... method body

                  }finally{

                         //在finally释放锁

                         lock.unlock();

                  }

           }

    }

    修改后的例子:

    //同步代码块

    package july7;

    class SellDemo implements Runnable{

        private int num = 50;

        @Override

        public void run() {

            for (int i = 0; i < 200; i++) {

                synchronized (this) {

                    if(num > 0){ 

                        try {

                        //因为它不可以直接调用getName()方法,所以必须要获取当前线程。

                            Thread.sleep(10);

                        } catch (InterruptedException e) {

                            e.printStackTrace();

                        }

                    System.out.println(Thread.currentThread().getName()+"卖出第"+num--+"张票!");

                    }

                }

            }

        }

    }

    public class Demo3 {

        public static void main(String[] args) {

            SellDemo s = new SellDemo();

            new Thread(s,"A").start();

            new Thread(s,"B").start();

            new Thread(s,"C").start();

        }

    }

    //同步方法

    package july7;

    //同步方法

    class FinalDemo1 implements Runnable {

        private int num = 50;

        @Override

        public void run() {

            for (int i = 0; i < 100; i++) {

                gen();

            }

        }

        public synchronized void gen() {

            for (int i = 0; i < 100; i++) {

                if (num > 0) {

                    try {

                        Thread.sleep(10);

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                    System.out.println(Thread.currentThread().getName() + "卖出了第"

                            + num-- + "张票!");

                }

            }

        }

    }

    public class Demo6 {

        public static void main(String[] args) {

            FinalDemo1 f = new FinalDemo1();

            new Thread(f, "A").start();

            new Thread(f, "B").start();

            new Thread(f, "C").start();

        }

    }

    //线程同步锁

    package july7;

    import java.util.concurrent.locks.ReentrantLock;

    //同步锁

    class FinalDemo2 implements Runnable {

        private int num = 50;

        private final ReentrantLock lock = new ReentrantLock();

       

        @Override

        public void run() {

            for (int i = 0; i < 100; i++) {

                gen();

            }

        }

        public void gen() {

            lock.lock();

            try{

                //for (int i = 0; i < 100; i++) {

                    if (num > 0) {

                        try {

                            Thread.sleep(10);

                        } catch (InterruptedException e) {

                            e.printStackTrace();

                        }

                        System.out.println(Thread.currentThread().getName() + "卖出了第"

                                + num-- + "张票!");

                    }

                //}

            }finally{

                lock.unlock();

            }

        }

    }

    public class Demo7 {

        public static void main(String[] args) {

            FinalDemo2 f = new FinalDemo2();

            new Thread(f, "A").start();

            new Thread(f, "B").start();

            new Thread(f, "C").start();

        }

    }

  • 相关阅读:
    jmeter_04_常用取样器
    jmeter_03_鉴权
    jmeter_02_目录文档说明
    jmeter_01_常用快捷键
    Web Api 与 Andriod 接口对接开发经验
    Eclipse自动生成作者、日期注释等功能设置
    c#解析XML到DATASET及dataset转为xml文件函数
    Jquery 仿 android Toast效果
    正在运行的android程序,按home键之后退回到桌面,在次点击程序图标避免再次重新启动程序解决办法
    异步网络加载开源框架AsyncHttpClient使用
  • 原文地址:https://www.cnblogs.com/fanweisheng/p/11132355.html
Copyright © 2020-2023  润新知