Java多线程中的原子类

March 9, 2015

先来看没有加锁的情况:

这个例子中我们想在pt类中对count进行累加, 两个线程各4次,最后应该输出8, 然而这个例子输出的结果从4-8都会出现,这就是典型的没有同步的例子.

public class Main  {

    public static void main(String[] args) throws Exception {

        ProcessingThread pt = new ProcessingThread();
        Thread t1 = new Thread(pt, "t1");
        t1.start();
        Thread t2 = new Thread(pt, "t2");
        t2.start();
        t1.join();
        t2.join();
        System.out.println("Processing count=" + pt.getCount());

    }
}
class ProcessingThread implements Runnable {
    private int count;


    @Override
    public void run() {
        for (int i = 1; i < 5; i++) {
            processSomething(i);
            count++;  //非原子操作
        }
    }


    public synchronized int getCount() {
        return this.count;
    }


    private void processSomething(int i) {
        // processing some job
        try {
            Thread.sleep(i * 100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

再来看看原子类:

这个例子中,我们使用的AtomicInteger的两个操作是原子操作,因此不会出现数据不一致的情况.

import java.util.concurrent.atomic.AtomicInteger;
 
 
public class JavaAtomic {
 
    public static void main(String[] args) throws InterruptedException {
 
        ProcessingThread pt = new ProcessingThread();
        Thread t1 = new Thread(pt, "t1");
        t1.start();
        Thread t2 = new Thread(pt, "t2");
        t2.start();
        t1.join();
        t2.join();
        System.out.println("Processing count=" + pt.getCount());
    }
 
}
 
 
class ProcessingThread implements Runnable {
    private AtomicInteger count = new AtomicInteger();
 
 
    @Override
    public void run() {
        for (int i = 1; i < 5; i++) {
            processSomething(i);
            count.incrementAndGet();  //原子操作
        }
    }
 
 
    public int getCount() {
        return this.count.get(); // 原子操作
    }
 
 
    private void processSomething(int i) {
        // processing some job
        try {
            Thread.sleep(i * 100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
 
}

synchronized例子

和上例结果一样,我们用synchronized关键字来实现

 
public class JavaAtomic {
 
    public static void main(String[] args) throws InterruptedException {
 
        ProcessingThread pt = new ProcessingThread();
        Thread t1 = new Thread(pt, "t1");
        t1.start();
        Thread t2 = new Thread(pt, "t2");
        t2.start();
        t1.join();
        t2.join();
        System.out.println("Processing count=" + pt.getCount());
    }
 
}
 
 
class ProcessingThread implements Runnable {
    private int count;
 
 
    @Override
    public void run() {
        for (int i = 1; i < 5; i++) {
            processSomething(i);
            synchronized(this) {
                count++;
            }
        }
    }
 
 
    public int getCount() {
        return this.count; // 原子操作
    }
 
 
    private void processSomething(int i) {
        // processing some job
        try {
            Thread.sleep(i * 100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
 
}