一、前言
Java里面进行多线程通信的主要方式就是共享内存的方式,共享内存主要的关注点有两个:可见性和有序性原子性。Java内存模型(JMM)解决了可见性和有序性的问题,而锁解决了原子性的问题,理想情况下我们希望做到“同步”和“互斥”。除了使用全局JVM内存共享方式(静态线程安全数据类型或分布式内存redis、memcached等),如需在用户线程上下文内存作用域范围。
二、代码示例
1、将数据抽象成一个类,并将对这个数据的操作作为这个类的方法(只要在方法上加“synchronized”)
package thread.share;@b@@b@public class ThreadData {@b@ @b@ private int j=0;@b@ @b@ public synchronized void add(){@b@ j++;@b@ System.out.println(Thread.currentThread().getName()+" add@j:"+j);@b@ }@b@ @b@ public synchronized void dec(){@b@ j--;@b@ System.out.println(Thread.currentThread().getName()+" dec@j:"+j);@b@ }@b@ @b@ public static void main(String[] args) throws Exception {@b@ ThreadData data=new ThreadData();@b@ AddRunnable add=new AddRunnable(data);@b@ DecRunnable dec=new DecRunnable(data);@b@ @b@ @b@ int add_time=10;@b@ while(add_time>0){@b@ new Thread(add).start();@b@ add_time--;@b@ }@b@ @b@ @b@ @b@ int desc_time=10;@b@ while(desc_time>0){@b@ new Thread(dec).start();@b@ desc_time--;@b@ }@b@ @b@ @b@ }@b@@b@}
package thread.share;@b@@b@public class AddRunnable implements Runnable {@b@ @b@ private ThreadData data;@b@ @b@ @b@ public AddRunnable(ThreadData data) {@b@ super();@b@ this.data = data;@b@ }@b@@b@@b@ @Override@b@ public void run() {@b@ data.add();@b@ }@b@@b@}
package thread.share;@b@@b@public class DecRunnable implements Runnable {@b@ @b@ private ThreadData data;@b@ @b@ @b@ public DecRunnable(ThreadData data) {@b@ super();@b@ this.data = data;@b@ }@b@@b@@b@ @Override@b@ public void run() {@b@ data.dec();@b@ }@b@@b@}
控制台运行结果
Thread-0 add@j:1@b@Thread-2 add@j:2@b@Thread-1 add@j:3@b@Thread-3 add@j:4@b@Thread-4 add@j:5@b@Thread-5 add@j:6@b@Thread-6 add@j:7@b@Thread-8 add@j:8@b@Thread-10 dec@j:7@b@Thread-11 dec@j:6@b@Thread-9 add@j:7@b@Thread-12 dec@j:6@b@Thread-13 dec@j:5@b@Thread-7 add@j:6@b@Thread-19 dec@j:5@b@Thread-16 dec@j:4@b@Thread-17 dec@j:3@b@Thread-18 dec@j:2@b@Thread-14 dec@j:1@b@Thread-15 dec@j:0
2、Runnable对象作为一个类的内部类
package thread.share;@b@@b@public class ThreadData2 {@b@ @b@ private int j=0;@b@ @b@ public synchronized void add(){@b@ j++;@b@ System.out.println(Thread.currentThread().getName()+" add@j:"+j);@b@ }@b@ @b@ public synchronized void dec(){@b@ j--;@b@ System.out.println(Thread.currentThread().getName()+" dec@j:"+j);@b@ }@b@ @b@ public static void main(String[] args) {@b@ @b@ final ThreadData2 data=new ThreadData2();@b@ @b@ int add_time=10;@b@ while(add_time>0){@b@ new Thread(new Runnable() {@b@ public void run() {@b@ data.add();@b@ }@b@ }).start();@b@ add_time--;@b@ }@b@ @b@ int desc_time=10;@b@ while(desc_time>0){@b@ new Thread(new Runnable() {@b@ public void run() {@b@ data.dec();@b@ }@b@ }).start();@b@ desc_time--;@b@ }@b@ @b@ @b@ }@b@@b@}
控制台运行结果
Thread-1 add@j:1@b@Thread-2 add@j:2@b@Thread-0 add@j:3@b@Thread-4 add@j:4@b@Thread-3 add@j:5@b@Thread-6 add@j:6@b@Thread-5 add@j:7@b@Thread-7 add@j:8@b@Thread-8 add@j:9@b@Thread-9 add@j:10@b@Thread-10 dec@j:9@b@Thread-11 dec@j:8@b@Thread-13 dec@j:7@b@Thread-12 dec@j:6@b@Thread-19 dec@j:5@b@Thread-17 dec@j:4@b@Thread-15 dec@j:3@b@Thread-16 dec@j:2@b@Thread-14 dec@j:1@b@Thread-18 dec@j:0