Java多线程资源共享

Java多线程资源共享

我们在编写Java多线程并发控制程序时,经常需要我们考虑到多个线程之间资源共享问题。那么,什么是资源共享问题?在Java多线程中资源共享就是多个线程共用同一个变量或者对象。下面通过模拟学生进教室线程阐述两种资源共享的方法。

1. 继承Thread类

每new一个Thread类或者子类对象时,非静态属性(实例属性)都会在内存中重新加载,起不到共用资源的效果,因此我们需要将共用的对象或者变量用static修饰,使其成为类属性,在内存中只加载一次。具体代码和结果如下:

Classroom类:

public class Classroom extends Thread {
    private static int studentNumber = 55;//学生人数
    private static int frontCount = 0;//前门人数
    private static int backCount = 0;//后门人数
    private static Object object = new Object();

    @Override
    public void run() {
        do {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (object) {
                if (studentNumber > 0) {
                    if (Thread.currentThread().getName().equals("前门")) {
                        frontCount++;
                    } else
                        backCount++;
                    System.out.println(Thread.currentThread().getName() + "有人进教室!");
                    studentNumber--;
                } else {
                    if (Thread.currentThread().getName().equals("前门"))
                        System.out.println(Thread.currentThread().getName() + "共进了" + frontCount + "学生");
                    else
                        System.out.println(Thread.currentThread().getName() + "共进了" + backCount + "学生");
                    break;
                }
            }

        } while (true);

    }
}

Test类:

public class TestDemo2_1 {
    public static void main(String[] args) {
        Classroom front=new Classroom();
        Classroom back=new Classroom();

        front.setName("前门");
        back.setName("后门");

        front.start();
        back.start();
    }
}

测试结果如下:

后门有人进教室!
前门有人进教室!
后门有人进教室!
前门有人进教室!
......
前门共进了27学生
后门共进了28学生

2. 通过实现Runnable接口

在Java中只能实现单继承,因此不能继承其他类,不适合资源共享,可以通过实现Runnable接口,通过同一个Runnable接口实现类对象创建多个线程,则多个线程共享Runnable对象。具体代码和结果如下:

IntoDoor类:

public class IntoDoor implements Runnable {
    private int studentNumber = 55;//学生人数
    private int frontCount = 0;//前门人数
    private int backCount = 0;//后门人数

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (this) {
                if (studentNumber > 0) {
                    if (Thread.currentThread().getName().equals("前门")) {
                        frontCount++;
                    } else
                        backCount++;
                    System.out.println(Thread.currentThread().getName() + "有人进教室!");
                    studentNumber--;
                } else {
                    if (Thread.currentThread().getName().equals("前门"))
                        System.out.println(Thread.currentThread().getName() + "共进了" + frontCount + "学生");
                    else
                        System.out.println(Thread.currentThread().getName() + "共进了" + backCount + "学生");
                    break;
                }
            }

        }

    }
}

Test类:

public class TestDemo2 {
    public static void main(String[] args) {
        IntoDoor Door =new IntoDoor();

        Thread front=new Thread(Door,"前门");
        Thread back=new Thread(Door,"后门");

        front.start();
        back.start();


    }
}

测试结果:

后门有人进教室!
前门有人进教室!
后门有人进教室!
前门有人进教室!
......
前门共进了27学生
后门共进了28学生
上一篇:7.ReadWriteLock的使用以及源码解读


下一篇:多线程-CountDownLatch,CyclicBarrier,Semaphore