Java线程:线程的同步-同步块

追其同步的根本的目的,是控制竞争资源的正确的访问,因此只要在访问竞争资源的时候保证同一时刻只能一个线程访问即可,因此Java引入了同步代码快的策略,以提高性能。

在上个例子的基础上,对oper方法做了改动,由同步方法改为同步代码块模式,程序的执行逻辑并没有问题。

/**
* Java线程:线程的同步-同步代码块
*
* @author leizhimin 
*/
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资源也没有意义,因为你占用着锁,其他互斥线程还是无法访问同步程序块。当然与同步程序块无关的线程可以获得更多的执行时间。

出处:http://lavasoft.blog.51cto.com/62575/221922

时间: 2024-09-26 12:48:14

Java线程:线程的同步-同步块的相关文章

JAVA之旅(十三)——线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this

JAVA之旅(十三)--线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this 我们继续上个篇幅接着讲线程的知识点 一.线程的安全性 当我们开启四个窗口(线程)把票陆陆续续的卖完了之后,我们要反思一下,这里面有没有安全隐患呢?在实际情况中,这种事情我们是必须要去考虑安全问题的,那我们模拟一下错误 package com.lgl.hellojava; import javax.security.auth.callback.TextInputCallback

java线程学习4——线程同步之同步代码块

  模拟一个场景,两个人对同一个账户同时取钱   package cn.xy.Thread; public class Account {  /**   * 账户号   */  private String accountNo;  /**   * 账户余额   */  private double balance;  public Account()  {   super();  }  public Account(String accountNo, double balance)  {   s

java关于线程同步的问题

问题描述 java关于线程同步的问题 package 线程.TestTeread_5; /* push和pop增加减少数组元素, 我的问题是: 为什么去掉push和pop的synchronized修饰关键词时,会报如下错误 异常: Exception in thread "Thread-0" java.lang.IllegalMonitorStateException at java.lang.Object.notify(Native Method) at 线程.TestTeread_

java中线程同步,线程让步,线程休眠的区别和联系是什么

问题描述 java中线程同步,线程让步,线程休眠的区别和联系是什么 java中线程同步,线程让步,线程休眠的区别和联系是什么 线程的本质还是一个运行中的类, 解决方案 线程同步:是保证多线程安全访问竞争资源的一种手段,java中常用的是加锁机制即synchronized同步代码块实现的. 线程让步的方法是yield(),休眠方法是sleep().sleep()方法和yield()方法都是Thread类的静态方法,都会使当前处于运行状态的线程放弃CPU,把运行机会让给别的线程. 两者的区别在于:s

基本线程同步(五)使用Lock同步代码块

声明:本文是< Java 7 Concurrency Cookbook >的第二章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞 使用Lock同步代码块 Java提供另外的机制用来同步代码块.它比synchronized关键字更加强大.灵活.它是基于Lock接口和实现它的类(如ReentrantLock).这种机制有如下优势: 它允许以一种更灵活的方式来构建synchronized块.使用synchronized关键字,你必须以结构化方式得到释

深入解析Java的线程同步以及线程间通信_java

Java线程同步 当两个或两个以上的线程需要共享资源,它们需要某种方法来确定资源在某一刻仅被一个线程占用.达到此目的的过程叫做同步(synchronization).像你所看到的,Java为此提供了独特的,语言水平上的支持. 同步的关键是管程(也叫信号量semaphore)的概念.管程是一个互斥独占锁定的对象,或称互斥体(mutex).在给定的时间,仅有一个线程可以获得管程.当一个线程需要锁定,它必须进入管程.所有其他的试图进入已经锁定的管程的线程必须挂起直到第一个线程退出管程.这些其他的线程被

Java多线程-线程的同步与锁的问题_java

一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. package cn.thread; public class Foo { private int x = 100; public int getX() { return x; } public int fix(int y) { x = x - y; return x; } } package cn.thread

java 实现线程同步的方式有哪些_java

什么是线程同步? 当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致),所以我们用同步机制来解决这些问题. 实现同步机制有两个方法: 1.同步代码块: synchronized(同一个数据){} 同一个数据:就是N条线程同时访问一个数据. 2. 同步方法: public synchronized 数据返回类型 方法名(){} 就是使用 synchronized 来修饰某个方法,则该方法称为同步方法.对于同步方法而言,无需显示指定同步监视器,同步

线程-同步代码块的问题。。。。。

问题描述 同步代码块的问题..... 数据库的几张表常用表的数据,我想写到几个静态变量中. 然后提供若干个get方法,同时还有一个set方法重置所有的静态变量. 请问如何能够在set重置方法没完成以前,让get方法的线程等待? 同时几个get方法又不能有相互影响. 就是set没完成,所有的get需要等待,但是不同的get之间没完成不需要等待. 来人啊... 解决方案 http://my.oschina.net/tinglanrmb32/blog/339661 解决方案二: http://blog