java中的线程同步实现方法一(将方法设置为synchronized)
2013-10-01 16:54
661 查看
一. 简要说明:
对于java中的线程同步来说,可以用synchronized关键字来修饰,既可以对方法进行修饰,也可以对变量进行修饰,而二者都可以实现线程的同步。本篇说的是第一种方法,第二种方法在下一篇中说明。
二. 例子:
AccountRunnable.java:
public class AccountRunnable implements Runnable {
private static float balance = 500;
private String name;
public AccountRunnable(String name){
this.name = name;
}
public void run(){
try {
while (true) {
deposit(1000);
withdraw(500);
getBalance();
Thread.sleep(300);
}
}
catch(Exception e) {
e.printStackTrace();
}
}
public synchronized void getBalance() {
System.out.println("getBalance" + balance);
}
public synchronized void deposit(float amount) {
System.out.println(name + "deposit " + amount);
balance = balance + amount;
}
public synchronized void withdraw(float amount) {
System.out.println(name + "withdraw " + amount);
balance = balance - amount;
}
}
ThreadSyncFunTest.java
public class ThreadSyncFunTest {
public static void main(String args[]) {
AccountRunnable r;
Thread t;
ThreadGroup tg = new ThreadGroup("my thread group");
for (int i=0; i<=2; i++) {
r = new AccountRunnable("account " + i);
t = new Thread(tg,r);
t.start();
}
try {
System.in.read();
tg.interrupt(); //采用中断只为了结束程序的运行
}
catch(Exception e) {
}
System.out.println("end main");
}
}
测试结果:
--------------------Configuration: <Default>--------------------
account 0 deposit: 1000.0
account 0 withdraw: 500.0
getBalance: 1000.0
account 2 deposit: 1000.0
account 2 withdraw: 500.0
getBalance: 1500.0
account 1 deposit: 1000.0
account 1 withdraw: 500.0
getBalance: 2000.0
account 0 deposit: 1000.0
account 0 withdraw: 500.0
getBalance: 2500.0
account 2 deposit: 1000.0
account 2 withdraw: 500.0
getBalance: 3000.0
account 1 deposit: 1000.0
account 1 withdraw: 500.0
getBalance: 3500.0
account 0 deposit: 1000.0
account 0 withdraw: 500.0
getBalance: 4000.0
account 2 deposit: 1000.0
account 2 withdraw: 500.0
getBalance: 4500.0
account 1 deposit: 1000.0
account 1 withdraw: 500.0
getBalance: 5000.0
account 0 deposit: 1000.0
account 0 withdraw: 500.0
getBalance: 5500.0
account 2 deposit: 1000.0
account 2 withdraw: 500.0
getBalance: 6000.0
account 1 deposit: 1000.0
account 1 withdraw: 500.0
getBalance: 6500.0
end main
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at AccountRunnable.run(AccountRunnable.java:15)
at java.lang.Thread.run(Unknown Source)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at AccountRunnable.run(AccountRunnable.java:15)
at java.lang.Thread.run(Unknown Source)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at AccountRunnable.run(AccountRunnable.java:15)
at java.lang.Thread.run(Unknown Source)
Process completed.
四. 说明与分析:
1. AccountRunnable类用于模拟3个会计师使用同一个帐户,各个会计会同时执行存款,提款和查询的操作,为了得到正确的结果,相关的3个方法必须实现同步化;
从测试结果仔细分析来看,计算结果都是正确的。
2. 在ThreadSyncFunTest 中,将生成的3个线程结合为一组,加入线程组,这样,可同时控制它们;
3. 利用线程组的中断来结束3个线程,同时,也意味着结束整个程序,所以,尽管会抛出异常,但是,这并不会影响整个程序的执行结果。当然,采用这种中断方式来结束程序的方法有些牵强。
对于java中的线程同步来说,可以用synchronized关键字来修饰,既可以对方法进行修饰,也可以对变量进行修饰,而二者都可以实现线程的同步。本篇说的是第一种方法,第二种方法在下一篇中说明。
二. 例子:
AccountRunnable.java:
public class AccountRunnable implements Runnable {
private static float balance = 500;
private String name;
public AccountRunnable(String name){
this.name = name;
}
public void run(){
try {
while (true) {
deposit(1000);
withdraw(500);
getBalance();
Thread.sleep(300);
}
}
catch(Exception e) {
e.printStackTrace();
}
}
public synchronized void getBalance() {
System.out.println("getBalance" + balance);
}
public synchronized void deposit(float amount) {
System.out.println(name + "deposit " + amount);
balance = balance + amount;
}
public synchronized void withdraw(float amount) {
System.out.println(name + "withdraw " + amount);
balance = balance - amount;
}
}
ThreadSyncFunTest.java
public class ThreadSyncFunTest {
public static void main(String args[]) {
AccountRunnable r;
Thread t;
ThreadGroup tg = new ThreadGroup("my thread group");
for (int i=0; i<=2; i++) {
r = new AccountRunnable("account " + i);
t = new Thread(tg,r);
t.start();
}
try {
System.in.read();
tg.interrupt(); //采用中断只为了结束程序的运行
}
catch(Exception e) {
}
System.out.println("end main");
}
}
测试结果:
--------------------Configuration: <Default>--------------------
account 0 deposit: 1000.0
account 0 withdraw: 500.0
getBalance: 1000.0
account 2 deposit: 1000.0
account 2 withdraw: 500.0
getBalance: 1500.0
account 1 deposit: 1000.0
account 1 withdraw: 500.0
getBalance: 2000.0
account 0 deposit: 1000.0
account 0 withdraw: 500.0
getBalance: 2500.0
account 2 deposit: 1000.0
account 2 withdraw: 500.0
getBalance: 3000.0
account 1 deposit: 1000.0
account 1 withdraw: 500.0
getBalance: 3500.0
account 0 deposit: 1000.0
account 0 withdraw: 500.0
getBalance: 4000.0
account 2 deposit: 1000.0
account 2 withdraw: 500.0
getBalance: 4500.0
account 1 deposit: 1000.0
account 1 withdraw: 500.0
getBalance: 5000.0
account 0 deposit: 1000.0
account 0 withdraw: 500.0
getBalance: 5500.0
account 2 deposit: 1000.0
account 2 withdraw: 500.0
getBalance: 6000.0
account 1 deposit: 1000.0
account 1 withdraw: 500.0
getBalance: 6500.0
end main
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at AccountRunnable.run(AccountRunnable.java:15)
at java.lang.Thread.run(Unknown Source)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at AccountRunnable.run(AccountRunnable.java:15)
at java.lang.Thread.run(Unknown Source)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at AccountRunnable.run(AccountRunnable.java:15)
at java.lang.Thread.run(Unknown Source)
Process completed.
四. 说明与分析:
1. AccountRunnable类用于模拟3个会计师使用同一个帐户,各个会计会同时执行存款,提款和查询的操作,为了得到正确的结果,相关的3个方法必须实现同步化;
从测试结果仔细分析来看,计算结果都是正确的。
2. 在ThreadSyncFunTest 中,将生成的3个线程结合为一组,加入线程组,这样,可同时控制它们;
3. 利用线程组的中断来结束3个线程,同时,也意味着结束整个程序,所以,尽管会抛出异常,但是,这并不会影响整个程序的执行结果。当然,采用这种中断方式来结束程序的方法有些牵强。
相关文章推荐
- Java实现内存可见性的两种方法比较:synchronized 和 Volatile以及涉及到锁的剖析
- java设置一段代码执行的超时时间的简单方法 间接实现获取Connection超时问题
- Java_基础—多线程(匿名内部类实现线程的两种方式和设置名字的方法)
- Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)
- java设置一段代码执行的超时时间的简单方法 间接实现获取Connection超时问题
- 如何实现多个线程同步 (2013-11-10 12:07:24)转载▼ 标签: it 在编写一个类时,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题,Java实现线程同步的方法很多
- 【098】Java利用对象池配合synchronized同步块实现较高效率的线程同步
- java中synchronized关键字实现线程同步互斥(一)
- JAVA学习笔记--多线程(三)synchronized实现线程同步
- 关于java synchronized修饰方法时实现线程互斥遇到的问题
- java设置session过期时间的实现方法
- java中的线程同步实现法二(Synchronized 程序段)
- JAVA多线程(五)用lock、synchronized、阻塞队列三种方法实现生产者消费者模式
- java实现同步map的几种方法(lock,synchronized,rwlock,ConcurrentHashMap,hashtable,SynchronizedMap)
- 【Java面试题】26 多线程有几种实现方法?同步有几种实现方法? 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
- java中实现线程同步的7种方法
- Java多线程系列三——实现线程同步的方法
- java实现线程同步的方法
- java设置session过期时间的实现方法
- 实现apk 调用framework java JNI中方法