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?