博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java多线程加锁是对谁加锁?
阅读量:6458 次
发布时间:2019-06-23

本文共 4043 字,大约阅读时间需要 13 分钟。

1.java多线程加锁是对谁加锁?

答:当然是对共享资源加锁啊,对谁进行访问修改,就对象进行加锁。以便使多线程按序访问此共享对象

 比如:

在具体的Java代码中需要完成一下两个操作:

把竞争访问的资源类Foo变量x标识为private;
同步哪些修改变量的代码,使用synchronized关键字同步方法或代码。

package cn.thread;public class Foo2 {    private int x = 100;    public int getX() {        return x;    }    //同步方法    public synchronized int fix(int y) {        x = x - y;        System.out.println("线程"+Thread.currentThread().getName() + "运行结束,减少“" + y                + "”,当前值为:" + x);        return x;    }    //    //同步代码块//    public int fix(int y) {//        synchronized (this) {//            x = x - y;//            System.out.println("线程"+Thread.currentThread().getName() + "运行结束,减少“" + y//                    + "”,当前值为:" + x);//        }//        //        return x;//    }}
package cn.thread;public class MyRunnable2  {    public static void main(String[] args) {        MyRunnable2 run = new MyRunnable2();        Foo2 foo2=new Foo2();                MyThread t1 = run.new MyThread("线程A", foo2, 10);        MyThread t2 = run.new MyThread("线程B", foo2, -2);        MyThread t3 = run.new MyThread("线程C", foo2, -3);        MyThread t4 = run.new MyThread("线程D", foo2, 5);                t1.start();        t2.start();        t3.start();        t4.start();    }        class MyThread extends Thread {        private Foo2 foo2;        /**当前值*/        private int y = 0;                MyThread(String name, Foo2 foo2, int y) {            super(name);            this.foo2 = foo2;            this.y = y;        }        public void run() {            foo2.fix(y);        }    }}
线程线程A运行结束,减少“10”,当前值为:90线程线程C运行结束,减少“-3”,当前值为:93线程线程B运行结束,减少“-2”,当前值为:95线程线程D运行结束,减少“5”,当前值为:90

比如:

对于同步,除了同步方法外,还可以使用同步代码块,有时候同步代码块会带来比同步方法更好的效果。

追其同步的根本的目的,是控制竞争资源的正确的访问,因此只要在访问竞争资源的时候保证同一时刻只能一个线程访问即可,因此Java引入了同步代码快的策略,以提高性能。
在上个例子的基础上,对oper方法做了改动,由同步方法改为同步代码块模式,程序的执行逻辑并没有问题。

package cn.thread;/** * 线程同步方法 *  * @author 林计钦 * @version 1.0 2013-7-24 上午10:12:47 */public class ThreadSynchronizedCode {    public static void main(String[] args) {        ThreadSynchronizedCode t = new ThreadSynchronizedCode();        User u = t.new User("张三", 100);        MyThread t1 = t.new MyThread("线程A", u, 20);        MyThread t2 = t.new MyThread("线程B", u, -60);        MyThread t3 = t.new MyThread("线程C", u, -80);        MyThread t4 = t.new MyThread("线程D", u, -30);        MyThread t5 = t.new MyThread("线程E", u, 32);        MyThread t6 = t.new MyThread("线程F", u, 21);        t1.start();        t2.start();        t3.start();        t4.start();        t5.start();        t6.start();    }    class MyThread extends Thread {        private User u;        /**存款金额*/        private int y = 0;                MyThread(String name, User u, int y) {            super(name);            this.u = u;            this.y = y;        }        public void run() {            u.oper(y);        }    }    class User {        /** 账号 */        private String code;        /** 余额 */        private int cash;        User(String code, int cash) {            this.code = code;            this.cash = cash;        }        public String getCode() {            return code;        }        public void setCode(String code) {            this.code = code;        }        /**         * 存款         *          * @param x 欲存款金额         *                     */        public void oper(int x) {            try {                Thread.sleep(10L);                synchronized (this) {                    this.cash += x;                    System.out.println("线程" + Thread.currentThread().getName() + "运行结束,增加“" + x                            + "”,当前用户账户余额为:" + cash);                }                Thread.sleep(10L);            } catch (InterruptedException e) {                e.printStackTrace();            }        }        @Override        public String toString() {            return "User{" + "code='" + code + '\'' + ", cash=" + cash + '}';        }    }}
线程线程B运行结束,增加“-60”,当前用户账户余额为:40线程线程A运行结束,增加“20”,当前用户账户余额为:60线程线程C运行结束,增加“-80”,当前用户账户余额为:-20线程线程D运行结束,增加“-30”,当前用户账户余额为:-50线程线程F运行结束,增加“21”,当前用户账户余额为:-29线程线程E运行结束,增加“32”,当前用户账户余额为:3

转载地址:http://icizo.baihongyu.com/

你可能感兴趣的文章
C# 获取编码
查看>>
mysql的数据类型int、bigint、smallint 和 tinyint取值范围
查看>>
利用网易获取所有股票数据
查看>>
移动铁通宽带上网设置教程
查看>>
Python算法(含源代码下载)
查看>>
利用Windows自带的Certutil查看文件MD5
查看>>
通过原生js添加div和css
查看>>
简单的导出表格和将表格下载到桌面上。
查看>>
《ArcGIS Engine+C#实例开发教程》第一讲桌面GIS应用程序框架的建立
查看>>
JAVA - 大数类详解
查看>>
查询指定名称的文件
查看>>
Python 嵌套列表解析
查看>>
[GXOI/GZOI2019]旧词——树链剖分+线段树
查看>>
anroid 广播
查看>>
AJAX POST&跨域 解决方案 - CORS
查看>>
关于最小生成树中的kruskal算法中判断两个点是否在同一个连通分量的方法总结...
查看>>
开篇,博客的申请理由
查看>>
Servlet 技术全总结 (已完成,不定期增加内容)
查看>>
[JSOI2008]星球大战starwar BZOJ1015
查看>>
CountDownLatch与thread-join()的区别
查看>>