你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:技术专栏 / Java专栏
Java线程:线程的同步-同步块
 
 对于同步,除了同步方法外,还可以使用同步代码块,有时候同步代码块会带来比同步方法更好的效果。追其同步的根本的目的,是控制竞争资源的正确的访问,因此只要在访问竞争资源的时候保证同一时刻只能一个线程访问即可,因此Java引入了同步代码快的策略,以提高性能。在上个例子的基础上,对oper方法做了改动,由同步方法改为同步代码块模式,程序的执行逻辑并没有问题。
/**
* Java线程:线程的同步-同步代码块
*
* @author leizhimin 2009-11-4 11:23:32
*/
public class Test {
        public static void main(String[] args) {
                User u = new User("张三", 100);
                MyThread t1 = new MyThread("线程A", u, 20);
                MyThread t2 = new MyThread("线程B", u, -60);
                MyThread t3 = new MyThread("线程C", u, -80);
                MyThread t4 = new MyThread("线程D", u, -30);
                MyThread t5 = new MyThread("线程E", u, 32);
                MyThread t6 = 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 添加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 +
                                '}';
        }
}
线程E运行结束,增加“32”,当前用户账户余额为:132
线程B运行结束,增加“-60”,当前用户账户余额为:72
线程D运行结束,增加“-30”,当前用户账户余额为:42
线程F运行结束,增加“21”,当前用户账户余额为:63
线程C运行结束,增加“-80”,当前用户账户余额为:-17
线程A运行结束,增加“20”,当前用户账户余额为:3

Process finished with exit code 0
注意:
        在使用synchronized关键字时候,应该尽可能避免在synchronized方法或synchronized块中使用sleep或者yield方法,因为synchronized程序块占有着对象锁,你休息那么其他的线程只能一边等着你醒来执行完了才能执行。不但严重影响效率,也不合逻辑。
        同样,在同步程序块内调用yeild方法让出CPU资源也没有意义,因为你占用着锁,其他互斥线程还是无法访问同步程序块。当然与同步程序块无关的线程可以获得更多的执行时间。
  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089