多线程访问共享数方式的总结

来源:互联网 发布:人体 3d 软件 编辑:程序博客网 时间:2024/05/23 13:56


1.多个线程访问共享数据的方式
多个线程访问共享数据分为两种方式:
1)每个线程执行操作共享数据的方式相同
2)每个线程执行操作共享数据的方式不同


2.多个线程执行操作共享数据的方式相同
如果每个线程执行操作共享数据的方式相同,那么可以使用同一个Runnable对象,将共享数据放在Runnable中并重写操作共享数据的run()方法。然后创建多个线程并将同一个Runnable对象作为参数传入线程的构造器中。例如售票系统。
//售票类class Tickets implements Runnable {//定义总票数为100private int tickets = 100;//重写run方法,封装运行代码public void run() {//循环售票while(true) {//同步代码块,使用本类字节码对象作为锁synchronized(Tickets.class) {//如果票数大于0,则可以继续出售。每售出一张,票数减一if(tickets > 0) {System.out.println(Thread.currentThread().getName() + "售出第" + (tickets--) + "号票");}}}}}public class TicketDemo {public static void main(String[] args) {// TODO Auto-generated method stubTickets tickets = new Tickets();//创建四个售票窗口Thread t1 = new Thread(tickets);Thread t2 = new Thread(tickets);Thread t3 = new Thread(tickets);Thread t4 = new Thread(tickets);//开始售票t1.start();t2.start();t3.start();t4.start();}}



3.多个线程执行操作共享数据的方式不同
如果每个线程执行操作共享数据的方式不同,可以有3中方式实现:
1)将共享数据封装在一个对象中,然后将此对象逐一传递给各个不同的Runnable,每个Runnable的run()封装不同操作共享数据的方法。
例:设计4个线程,其中2个线程每次对j加1,另外两个线程每次对j减1。
//定义Data类封装数据jclass Data {private int j = 0;//对j进行加1的操作,因为要设计多线程访问,所以是同步方法public synchronized void increment(){System.out.println("对j加1后j的值为:" + (++j));}//对j进行减1的操作public synchronized void decrement(){System.out.println("对j减1后j的值为:" + (--j));}}//定义MyRunnalbePlus对j进行加操作class MyRunnalbePlus implements Runnable{private Data data;public MyRunnalbePlus(Data data){this.data = data;}@Overridepublic void run() {while(true){data.increment();}}}//定义MyRunnalbeDec对j进行加操作class MyRunnalbeDec implements Runnable{private Data data;public MyRunnalbeDec(Data data){this.data = data;}@Overridepublic void run() {while(true){data.decrement();}}}public class MultiThreadShareData {public static void main(String[] args) {// TODO Auto-generated method stubData data = new Data();//将同一个data作为参数传入Runnable对象MyRunnalbePlus plus = new MyRunnalbePlus(data);MyRunnalbeDec dec = new MyRunnalbeDec(data);//分别开启两个加j和减j的线程for(int i = 0; i < 2; i++){new Thread(plus).start();new Thread(dec).start();}}}

2)将不同操作共享数据的Runnable作为某一个类的内部类,共享数据作为外部类的成员变量。
public class MultiThreadShareData {//共享数据作为外部类成员变量private static int j = 0;//对j进行加1的操作,因为要设计多线程访问,所以是同步方法public static synchronized void increment(){System.out.println("对j加1后j的值为:" + (++j));}//对j进行减1的操作public static synchronized void decrement(){System.out.println("对j减1后j的值为:" + (--j));}//将Runnable定义为内部类static class Inc implements Runnable{@Overridepublic void run() {while(true)increment();}}static class Dec implements Runnable{@Overridepublic void run() {while(true)decrement();}}public static void main(String[] args) {// TODO Auto-generated method stub//创建不同的RunnableInc inc = new Inc();Dec dec = new Dec();for(int i = 0; i < 2; i++){new Thread(inc).start();new Thread(dec).start();}}}




3)上面两种方式的组合:将共享数据封装在一个对象中,每个线程对共享数据的操作也由该对象完成。对象作为外部类的成员变量,而Runnable定义为内部类。
//定义Data类封装数据jclass Data {private int j = 0;//对j进行加1的操作,因为要设计多线程访问,所以是同步方法public synchronized void increment(){System.out.println("对j加1后j的值为:" + (++j));}//对j进行减1的操作public synchronized void decrement(){System.out.println("对j减1后j的值为:" + (--j));}}public class MultiThreadShareData {//将共享数据作为类的成员变量private static Data data = new Data();public static void main(String[] args) {// TODO Auto-generated method stub//将不同操作共享数据的Runnable作为内部类。//此处为匿名内部类for(int i = 0; i < 2; i++){new Thread(new Runnable(){@Overridepublic void run() {while(true)data.increment();}}).start();new Thread(new Runnable(){@Overridepublic void run() {while(true)data.decrement();}}).start();}}}


0 0
原创粉丝点击