0 0

如何使用synchronized使多个线程同步?5

有个Bank类, 属性money=0;然后创建三个线程,调用addmoney()往bank里面加钱,
我这样写,为什么不能同步呢 ?  结果不是300万呀?新手请指教.

public class Bank {
private int money=0;

public int getMoney() {
return money;
}

public void setMoney(int money) {
this.money = money;
}

public  void addMoney(int money){
this.money+=money;
}
public void subMoney(int money){
this.money-=money;
}
}


public class test2 implements Runnable {
private Bank bank;

public test2(Bank bank) {
this.bank = bank;
}

@Override
public synchronized void run() {
for (int i = 0; i < 1000; i++) {
bank.addMoney(1000);
}
}

public static void main(String[] args) {
Bank bank = new Bank();
test2 r1 = new test2(bank);
test2 r2 = new test2(bank);
test2 r3 = new test2(bank);
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
Thread t3 = new Thread(r3);
t1.start();
t2.start();
t3.start();
System.out.println(bank.getMoney());
}
}
2014年7月29日 20:01

7个答案 按时间排序 按投票排序

0 0

采纳的答案

如有我现在用同一个runable实例去构造线程,结果就很明显了。

Thread t1 = new Thread(r1);
		Thread t2 = new Thread(r1);
		Thread t3 = new Thread(r1);
		t1.start();
		t2.start();
		t3.start();
		System.out.println(bank.getMoney());

输出:
引用
0
Thread-0:befor:2014-07-29 11:19:34.000034:$0
Thread-0:after:2014-07-29 11:19:34.000034:$1000
Thread-0:befor:2014-07-29 11:19:34.000034:$1000
Thread-0:after:2014-07-29 11:19:34.000034:$2000
Thread-0:befor:2014-07-29 11:19:34.000034:$2000
Thread-0:after:2014-07-29 11:19:34.000034:$3000
Thread-0:befor:2014-07-29 11:19:34.000034:$3000
Thread-0:after:2014-07-29 11:19:34.000034:$4000
Thread-0:befor:2014-07-29 11:19:34.000034:$4000
Thread-0:after:2014-07-29 11:19:34.000034:$5000
Thread-0:befor:2014-07-29 11:19:34.000034:$5000
Thread-0:after:2014-07-29 11:19:34.000034:$6000
Thread-0:befor:2014-07-29 11:19:34.000034:$6000
Thread-0:after:2014-07-29 11:19:34.000034:$7000
Thread-0:befor:2014-07-29 11:19:34.000034:$7000
Thread-0:after:2014-07-29 11:19:34.000034:$8000
Thread-0:befor:2014-07-29 11:19:34.000034:$8000
Thread-0:after:2014-07-29 11:19:34.000034:$9000
Thread-0:befor:2014-07-29 11:19:34.000034:$9000
Thread-0:after:2014-07-29 11:19:34.000034:$10000
Thread-2:befor:2014-07-29 11:19:34.000034:$10000
Thread-2:after:2014-07-29 11:19:34.000034:$11000
Thread-2:befor:2014-07-29 11:19:34.000034:$11000
Thread-2:after:2014-07-29 11:19:34.000034:$12000
Thread-2:befor:2014-07-29 11:19:34.000034:$12000
Thread-2:after:2014-07-29 11:19:34.000034:$13000
Thread-2:befor:2014-07-29 11:19:34.000034:$13000
Thread-2:after:2014-07-29 11:19:34.000034:$14000
Thread-2:befor:2014-07-29 11:19:34.000034:$14000
Thread-2:after:2014-07-29 11:19:34.000034:$15000
Thread-2:befor:2014-07-29 11:19:34.000034:$15000
Thread-2:after:2014-07-29 11:19:34.000034:$16000
Thread-2:befor:2014-07-29 11:19:34.000034:$16000
Thread-2:after:2014-07-29 11:19:34.000034:$17000
Thread-2:befor:2014-07-29 11:19:34.000034:$17000
Thread-2:after:2014-07-29 11:19:34.000034:$18000
Thread-2:befor:2014-07-29 11:19:34.000034:$18000
Thread-2:after:2014-07-29 11:19:34.000034:$19000
Thread-2:befor:2014-07-29 11:19:34.000034:$19000
Thread-2:after:2014-07-29 11:19:34.000034:$20000
Thread-1:befor:2014-07-29 11:19:34.000034:$20000
Thread-1:after:2014-07-29 11:19:34.000034:$21000
Thread-1:befor:2014-07-29 11:19:34.000034:$21000
Thread-1:after:2014-07-29 11:19:34.000034:$22000
Thread-1:befor:2014-07-29 11:19:34.000034:$22000
Thread-1:after:2014-07-29 11:19:34.000034:$23000
Thread-1:befor:2014-07-29 11:19:34.000034:$23000
Thread-1:after:2014-07-29 11:19:34.000034:$24000
Thread-1:befor:2014-07-29 11:19:34.000034:$24000
Thread-1:after:2014-07-29 11:19:34.000034:$25000
Thread-1:befor:2014-07-29 11:19:34.000034:$25000
Thread-1:after:2014-07-29 11:19:34.000034:$26000
Thread-1:befor:2014-07-29 11:19:34.000034:$26000
Thread-1:after:2014-07-29 11:19:34.000034:$27000
Thread-1:befor:2014-07-29 11:19:34.000034:$27000
Thread-1:after:2014-07-29 11:19:34.000034:$28000
Thread-1:befor:2014-07-29 11:19:34.000034:$28000
Thread-1:after:2014-07-29 11:19:34.000034:$29000
Thread-1:befor:2014-07-29 11:19:34.000034:$29000
Thread-1:after:2014-07-29 11:19:34.000034:$30000

2014年7月29日 23:23
0 0

synchronized  为什么加载 线程里面的run上面了?
应该加在addMoney()吧。

2014年7月30日 11:37
0 0

我觉得楼主还是先去把,同步和synchronized看下.
1.线程和线程调用类/方法/字段 没有关联关系
2.你只需要对调用类/方法/字段 加上安全锁就行了
3.至于实现,楼上给出了.百度一大堆

2014年7月30日 09:58
0 0

你的思维是一个线程一个线程的跑 最后数据累加 执行main方法打印出来,
因为run方法加了锁 所以在有线程进入的时候 另外的线程好像是不能进去 要等待这个线程执行完 释放资源 然后第二个线程进入直到第三个线程

而你又用的是main是主线程所以在你执行完第一个 main方法就开始执行没有等另外的线程走完 而直接打印数据,只需要在main加入 join 等待线程每个线程执行完成 打印的就是最后的数据累加

修改代码如下:

package cn.com.wangxiuwei.test;

public class test2 implements Runnable{

private Bank bank;

public test2(Bank bank) {
this.bank = bank;
}

public synchronized void run() {
for (int i = 0; i < 1000; i++) {
bank.addMoney(1000);
}
}

public static void main(String[] args) throws InterruptedException {
Bank bank = new Bank();
test2 r1 = new test2(bank);
test2 r2 = new test2(bank);
test2 r3 = new test2(bank);
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
Thread t3 = new Thread(r3);
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
System.out.println(bank.getMoney());
}


}

采纳就采纳 rmzdb 这个小伙解决问题很积极 精神值得我们学习 呵呵

2014年7月30日 02:49
0 0

如果把money改为static呢?

2014年7月30日 00:10
0 0

首先楼主没有理解线程的概念,start();只是启动线程,有没有结束另说呢,这里肯定是得不到的300w。如果在输出上方加上如下3句话后,是可以得到300w的数据的。

t1.join();
t2.join();
t3.join();


第二个问题,同步的问题,我该写了你的代码test2 类,你自己看看吧,看看能不能直观的看到问题:
import java.text.SimpleDateFormat;
import java.util.Date;

public class test2 implements Runnable {
	public static SimpleDateFormat f = new SimpleDateFormat(
			"yyyy-MM-dd hh:mm:ss.ssssss");

	private Bank bank;

	public test2(Bank bank) {
		this.bank = bank;
	}

	public synchronized void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName()+":befor:"+f.format(new Date())+":$"+bank.getMoney());
			bank.addMoney(1000);
			System.out.println(Thread.currentThread().getName()+":after:"+f.format(new Date())+":$"+bank.getMoney());
		}
	}

	public static void main(String[] args) throws InterruptedException {
		Bank bank = new Bank();
		test2 r1 = new test2(bank);
		test2 r2 = new test2(bank);
		test2 r3 = new test2(bank);
		Thread t1 = new Thread(r1);
		Thread t2 = new Thread(r2);
		Thread t3 = new Thread(r3);
		t1.start();
		t2.start();
		t3.start();
		System.out.println(bank.getMoney());
	}
}


输出:
引用
0
Thread-0:befor:2014-07-29 11:09:06.000006:$0
Thread-0:after:2014-07-29 11:09:06.000006:$1000
Thread-0:befor:2014-07-29 11:09:06.000006:$1000
Thread-0:after:2014-07-29 11:09:06.000006:$2000
Thread-0:befor:2014-07-29 11:09:06.000006:$2000
Thread-0:after:2014-07-29 11:09:06.000006:$3000
Thread-0:befor:2014-07-29 11:09:06.000006:$3000
Thread-0:after:2014-07-29 11:09:06.000006:$4000
Thread-0:befor:2014-07-29 11:09:06.000006:$4000
Thread-0:after:2014-07-29 11:09:06.000006:$5000
Thread-0:befor:2014-07-29 11:09:06.000006:$5000
Thread-0:after:2014-07-29 11:09:06.000006:$6000
Thread-2:befor:2014-07-29 11:09:06.000006:$5000
Thread-0:befor:2014-07-29 11:09:06.000006:$6000
Thread-2:after:2014-07-29 11:09:06.000006:$8000
Thread-0:after:2014-07-29 11:09:06.000006:$8000
Thread-0:befor:2014-07-29 11:09:06.000006:$8000
Thread-0:after:2014-07-29 11:09:06.000006:$9000
Thread-0:befor:2014-07-29 11:09:06.000006:$9000
Thread-0:after:2014-07-29 11:09:06.000006:$10000
Thread-0:befor:2014-07-29 11:09:06.000006:$10000
Thread-0:after:2014-07-29 11:09:06.000006:$11000
Thread-1:befor:2014-07-29 11:09:06.000006:$11000
Thread-1:after:2014-07-29 11:09:06.000006:$12000
Thread-2:befor:2014-07-29 11:09:06.000006:$8000
Thread-2:after:2014-07-29 11:09:06.000006:$13000
Thread-2:befor:2014-07-29 11:09:06.000006:$13000
Thread-2:after:2014-07-29 11:09:06.000006:$14000
Thread-2:befor:2014-07-29 11:09:06.000006:$14000
Thread-2:after:2014-07-29 11:09:06.000006:$15000
Thread-2:befor:2014-07-29 11:09:06.000006:$15000
Thread-2:after:2014-07-29 11:09:06.000006:$16000
Thread-2:befor:2014-07-29 11:09:06.000006:$16000
Thread-2:after:2014-07-29 11:09:06.000006:$17000
Thread-2:befor:2014-07-29 11:09:06.000006:$17000
Thread-2:after:2014-07-29 11:09:06.000006:$18000
Thread-2:befor:2014-07-29 11:09:06.000006:$18000
Thread-2:after:2014-07-29 11:09:06.000006:$19000
Thread-2:befor:2014-07-29 11:09:06.000006:$19000
Thread-2:after:2014-07-29 11:09:06.000006:$20000
Thread-2:befor:2014-07-29 11:09:06.000006:$20000
Thread-2:after:2014-07-29 11:09:06.000006:$21000
Thread-1:befor:2014-07-29 11:09:06.000006:$17000
Thread-1:after:2014-07-29 11:09:06.000006:$22000
Thread-1:befor:2014-07-29 11:09:06.000006:$22000
Thread-1:after:2014-07-29 11:09:06.000006:$23000
Thread-1:befor:2014-07-29 11:09:06.000006:$23000
Thread-1:after:2014-07-29 11:09:06.000006:$24000
Thread-1:befor:2014-07-29 11:09:06.000006:$24000
Thread-1:after:2014-07-29 11:09:06.000006:$25000
Thread-1:befor:2014-07-29 11:09:06.000006:$25000
Thread-1:after:2014-07-29 11:09:06.000006:$26000
Thread-1:befor:2014-07-29 11:09:06.000006:$26000
Thread-1:after:2014-07-29 11:09:06.000006:$27000
Thread-1:befor:2014-07-29 11:09:06.000006:$27000
Thread-1:after:2014-07-29 11:09:06.000006:$28000
Thread-1:befor:2014-07-29 11:09:06.000006:$28000
Thread-1:after:2014-07-29 11:09:06.000006:$29000
Thread-1:befor:2014-07-29 11:09:06.000006:$29000
Thread-1:after:2014-07-29 11:09:06.000006:$30000


最后罗嗦一句,不给我分 天理不容的  打了这么多字  我tmd太有奉献精神了

2014年7月29日 23:13
0 0

synchronized(bank) {
     // .....
}

2014年7月29日 20:16

相关推荐

    使用synchronized实现多线程同步.pdf

    在Java编程中,多线程同步是一个至关重要的概念,它确保了多个线程在访问共享资源时能够有序进行,防止数据不一致性和竞态条件。`synchronized`关键字是Java中实现线程同步的主要手段之一。这篇文档主要讨论了如何...

    使用synchronized实现多线程同步[借鉴].pdf

    线程同步的主要目的是保护共享资源的安全性,防止多个线程同时修改导致数据不一致。在Java中,除了`synchronized`关键字,还有`java.util.concurrent`包下的各种工具类,如`ReentrantLock`、`Semaphore`等,它们...

    Java多线程同步.pdf

    * 在社交媒体平台中,使用Java多线程同步机制来确保多个用户同时发布消息的正确执行。 * 在电子商务平台中,使用Java多线程同步机制来确保多个用户同时下订单的正确执行。 Java多线程同步机制是Java语言中的一种...

    简单实现多线程同步示例(模拟购票系统)

    线程同步是多线程编程中的关键概念,它防止了多个线程同时访问共享资源,避免了数据的不一致性,例如竞态条件和死锁。 在这个模拟购票系统中,我们可以设想有一个全局的票数变量。当多个用户同时尝试购买时,如果不...

    Java多线程同步机制研究分析.pdf

    synchronized方法的使用可以确保多个线程不会同时访问共享资源,避免了线程安全问题。 四、synchronized块的使用 synchronized块是Java多线程同步机制中的一种同步方式。它可以将程序的某段代码使用synchronized块...

    Java使用synchronized修饰方法来同步线程的实例演示

    如果多个线程互相持有对方需要的锁,可能会导致死锁,这时需要使用更高级的并发控制策略。 - 只有对共享资源进行同步才是必要的。如果一个方法或代码块不涉及共享数据,就没有必要使用synchronized。 6. **其他...

    基于Java synchronized同步锁实现线程交互.pdf

    Java synchronized同步锁可以保证同一时刻只有一个线程操作同一资源,使用wait()、notify()切换线程状态保证线程操作的前后顺序实现线程交互。 Java线程状态有五种:新建状态、就绪状态、运行状态、休眠状态和死亡...

    java的线程同步机制synchronized关键字的理解_.docx

    Java 的线程同步机制是为了解决多个线程共享同一片存储空间所带来的访问冲突问题。其中,synchronized 关键字是 Java 语言中解决这种冲突的重要机制。 synchronized 关键字的作用 synchronized 关键字可以作为函数...

    NET多线程同步方法详解

    .NET中的多线程同步是确保在并发环境下多个线程安全访问共享资源的关键技术。本文将深入探讨.NET框架中实现线程同步的多种方法。 首先,我们来看自由锁(InterLocked)。自由锁主要通过Interlocked类提供的静态方法来...

    正确使用多线程同步锁@synchronized()1

    总结起来,`@synchronized`是一种便捷的多线程同步手段,通过递归互斥锁实现代码的原子性。在使用时应注意以下几点: 1. `@synchronized`是基于对象的,传入的对象不能为`nil`,否则无效。 2. 由于使用了递归锁,它...

    多线程同步和通讯完整示例

    首先,多线程是指在一个程序中同时运行多个独立的执行线程,每个线程都有自己的程序计数器、系统栈和局部变量。在Java中,通过创建Thread对象或者实现Runnable接口可以创建线程。 ### 一、synchronized 关键字 `...

    java Thread & synchronized & concurrent 线程、同步、并发

    同步是控制多个线程对共享资源访问的一种机制,以防止数据不一致和竞态条件。Java提供了`synchronized`关键字来实现线程同步。当一个方法或代码块被`synchronized`修饰时,同一时刻只能有一个线程访问该区域。这样...

    多线程的批量线程同步解决方案

    多线程是指在一个进程中同时执行多个线程。这使得应用程序能够并行处理任务,提高系统资源利用率,尤其是在多核处理器中,可以显著提升性能。Java、Python、C++等编程语言都提供了丰富的多线程支持。 二、线程同步 ...

    java 多线程同步方法的实例

    在Java编程语言中,多线程同步是一种控制多个线程并发执行的重要机制,它确保了共享资源的安全访问,防止数据不一致性和竞态条件的发生。本文将深入探讨Java中的多线程同步方法,并通过实例来阐述其工作原理。 首先...

    java 线程同步 信号量控制同步

    线程同步是 Java 编程中的一种机制,用于控制多个线程之间的资源访问顺序,以避免线程之间的冲突和数据不一致。线程同步的目的就是避免线程“同步”执行,即让多个线程之间排队操作共享资源。 关于线程同步,需要...

    线程同步面试题深入解析

    在Java中,线程同步主要通过`synchronized`关键字来实现,防止多个线程同时访问临界区,以避免出现不可预期的结果。 1. **synchronized修饰同步方法** 使用`synchronized`关键字修饰的方法称为同步方法。同步方法...

    JNI 多线程同步机制的源码实现

    本文将深入探讨如何使用JNI实现多线程同步,并通过源码来解析这一过程。 1. **JNI基础知识** JNI为Java程序员提供了一种方式,可以在Java代码中调用本地方法,反之亦然。它定义了一系列的函数,例如`FindClass`...

    操作系统实验 多线程同步与互斥 java编写 有界面

    当多个线程访问并修改同一块数据时,如果没有适当的同步机制,可能会导致结果的不确定性,这被称为竞态条件。为了解决这个问题,Java提供了多种同步机制。 1. **synchronized关键字**:这是Java中的一种内置锁机制...

Global site tag (gtag.js) - Google Analytics