读书人

Java 软件开发工作记要

发布时间: 2012-08-30 09:55:54 作者: rapoo

Java 软件开发工作记录

2012/05/29

之前学习线程同步很迷糊,但是通过实践慢慢理解了一点点。

?

?

package com.ibatis.threads.demo1;import java.util.Collections;import java.util.LinkedList;import java.util.List;@SuppressWarnings("unchecked")public class NameList {private List nameList = Collections.synchronizedList(new LinkedList());public  void add(String name){nameList.add(name);}public  void removeFirst(String threadName){System.out.println(nameList.size());StringBuffer sb = new StringBuffer();sb.append(threadName).append("集合大小:").append(nameList.size()).append("移除对象:").append(nameList.size() > 0 ? (String) nameList.remove(0) : "null");System.out.println(sb.toString());}}

?

?

? ??package com.ibatis.threads.demo1;

public class Test {public static void main(String[] args) {final NameList nl = new NameList();nl.add("aaa");class NameDropper extends Thread {public void run() {nl.removeFirst(Thread.currentThread().getName());}}Thread t1 = new NameDropper();Thread t2 = new NameDropper();t1.start();t2.start();}}

?

? ? 在Test类中输出结果为:

?

? ? ?1

Thread-0集合大小:1移除对象:aaa1Thread-1集合大小:0移除对象:null

?

? ? 说明了Thread-0线程和Thread-1线程都查询到了集合非空,这样的就存在数据错误了,怎么错误??Thread-0明明就移除aaa集合为0了,但是Thread-1 查询还是为1. 因此虽然说是线程同步的集合但是也是不安全的,所以也要为方法上锁同步,更改代码如下:

?

? ??package com.ibatis.threads.demo1;

import java.util.Collections;import java.util.LinkedList;import java.util.List;@SuppressWarnings("unchecked")public class NameList {private List nameList = Collections.synchronizedList(new LinkedList());public synchronized void add(String name){nameList.add(name);}public synchronized void removeFirst(String threadName){System.out.println(nameList.size());StringBuffer sb = new StringBuffer();sb.append(threadName).append("集合大小:").append(nameList.size()).append("移除对象:").append(nameList.size() > 0 ? (String) nameList.remove(0) : "null");System.out.println(sb.toString());System.out.println(nameList.size());}}

?

? ? 同样用Test类输出,结果就准确了。如下:

?

? ??1

Thread-0集合大小:1移除对象:aaa0Thread-1集合大小:0移除对象:null

?

? ? 线程的交互

?

? ??package com.ibatis.threads.demo3;

public class ThreadB extends Thread{long total = 0l;@Overridepublic void run() {synchronized (this) {for (long i = 0; i < 299999999; i++) {total +=i;}//(完成计算了)唤醒在此对象监视器上等待的单个线程,在本例中线程A被唤醒notify();}}public static void main(String[] args) {long result = 0l;for (long i = 1; i < 299999999; i++) {result +=i;}System.out.println(result);}}

?

? ??package com.ibatis.threads.demo3;

public class ThreadA {public static void main(String[] args) {ThreadB b = new ThreadB();// 启动计算线程b.start();// 线程A拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者//synchronized (b) {//try {//System.out.println("等待对象b完成计算。。。");//// 当前主线程A等待//b.wait();//} catch (Exception e) {//// TODO Auto-generated catch block//e.printStackTrace();//}//System.out.println("b对象计算的总和是:" + b.total);//}System.out.println("等待对象b完成计算。。。");System.out.println("b对象计算的总和是:" + b.total);}}
?

?

? ? 如果不同步数据,线程B将没有计算完就输出结果了。如下:

?

? ??等待对象b完成计算。。。

b对象计算的总和是:2975580或等待对象b完成计算。。。b对象计算的总和是:8366095
?

?

? ? 看到上数据,表示数据的不同步性,所以要让线程A拥有b对象上的锁,修改代码:

?

? ? ?package com.ibatis.threads.demo3;

public class ThreadA {public static void main(String[] args) {ThreadB b = new ThreadB();// 启动计算线程b.start();// 线程A拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者synchronized (b) {try {System.out.println("等待对象b完成计算。。。");// 当前主线程A等待b.wait();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("b对象计算的总和是:" + b.total);}}}
?

? ? 结果如下:

?

? ??等待对象b完成计算。。。

b对象计算的总和是:44999999550000001

?

?

?

jdom 解析xml

?

读书人网 >编程

热点推荐