Java多线程(2)

Java多线程(2)

线程间的通信

线程间的通信又称为进程内通信,多个线程实现互斥访问共享资源时会互相发送信号或等待信号

等待通知机制

厨师与服务员的交互在桌子上:

  • 厨师做完一道菜的时间不确定,所以厨师将菜放到桌子上的时间也不确定

  • 服务员取到菜的时间取决于厨师,所以服务员有“等待”的状态

  • 服务员怎么能拿到菜?取决于厨师,厨师将菜放到桌子上,就相当于通知服务员拿菜了

这个过程就体现了等待通知机制

wait() notif()

wait():

调用后,这会强制当前线程等待,直到某个其他线程在同一个对象上调用notify()或notifyAll()

为此,当前线程必须拥有对象的监视器。这可能发生在:

  • 我们已经为给定对象执行了同步实例方法

  • 我们在给定对象上执行了synchronized块的主体

  • 通过为Class类型的对象执行同步静态方法

notify():

对于在此对象的监视器上等待的所有线程(通过使用任何一个wait()方法),方法notify()通知任何一个线程任意唤醒。确切唤醒哪个线程的选择是非确定性的 ,取决于实现。

notifyAll():

方法只是唤醒正在此对象的监视器上等待的所有线程

说明:

执行完notify()后,当前线程不会马上释放对象锁,呈wait状态的线程也不能马上获得对象锁,要等到执行notify()方法的线性将程序执行完毕后,当前线程才释放锁

如果第一个获得对象锁的wait线程执行完后,没有再次使用notify,则即便对象锁已经空闲,其他wait状态的线程由于没有通知也继续处于wait状态

例子:

模拟图片下载后查看的过程,图片是要下载完成之后才能执行查看这个操作


public class T1 {

    public static void main(String[] args) {
        //写两个线程 1.图片下载
        Object obj=new Object();
        Thread download=new Thread(){
            public void run() {
                System.out.println("开始下载图片");
                for (int i = 0; i < 101; i+=10) {
                    System.out.println("down"+i+"%");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("图片下载成功");
                synchronized (obj) {
                    obj.notify();//唤起
                }
                System.out.println("开始下载附件");
                for (int i = 0; i < 101; i+=10) {
                    System.out.println("附件下载"+i+"%");

                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("附件下载成功");
            }
        };
        //2.图片展示
        Thread show=new Thread(){
            public void run(){
                synchronized (obj) {
                    try {
                        obj.wait();//阻塞当前
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("show:开始展示图片");
                    System.out.println("图片展示完毕");
                }

            }
        };
        download.start();
        show.start();
    }

}

来看生产者/消费者的例子:

一个生产者和一个消费者共同操作一个栈,栈最大容量为1


public class MyStack {

    private List list = new ArrayList();

    synchronized public void push(){
        try {

            if (list.size() == 1){
                this.wait();
            }

            list.add("any = " + Math.random());
            this.notify();
            System.out.println("push  " + list.size());
        } catch (InterruptedException e){
            e.printStackTrace();
        }
    }

    synchronized public String pop(){
        String val = "";
        try {
            if (list.size() == 0){
                System.out.println("pop "+Thread.currentThread().getName());
                this.wait();
            }
            val = "" + list.get(0);
            list.remove(0);
            this.notify();
            System.out.println("pop " + list.size());
        } catch (InterruptedException e){
            e.printStackTrace();
        }

        return val;
    }

}

public class C {

    private MyStack myStack;

    public C(MyStack myStack) {
        this.myStack = myStack;
    }

    public void popService(){
        System.out.println("pop " + myStack.pop());
    }
}

public class P {

    private MyStack myStack;

    public P(MyStack myStack) {
        this.myStack = myStack;
    }

    public void pushService(){
        myStack.push();
    }
}


public class C_thread extends Thread{

    private C c;

    public C_thread(C c) {
        this.c = c;
    }

    @Override
    public void run() {
        while (true){
            c.popService();
        }
    }
}


public class P_thread extends Thread{

    private P p;

    public P_thread(P p) {
        this.p = p;
    }

    @Override
    public void run() {
        while (true){
            p.pushService();
        }
    }
}




public class Run {


//    生产者 消费者  容器size不会大于1
    public static void main(String[] args) {

        MyStack myStack = new MyStack();
        P p = new P(myStack);
        C c = new C(myStack);
        P_thread p_thread = new P_thread(p);
        C_thread c_thread = new C_thread(c);
        p_thread.start();
        c_thread.start();

    }
}


多个生产者多个消费者:

public class MyStack {

    private List list = new ArrayList();

    synchronized public void push(){
        try {

//            当一个生产者 多个消费者操作栈  会出现假死现象
//            应该push中使用了if判断
//            将 if 改成 while
//            以及notify 改成 notifyAll

            while (list.size() == 1){
                this.wait();
            }

            list.add("any = " + Math.random());
            this.notifyAll();
            System.out.println("push  " + list.size());
        } catch (InterruptedException e){
            e.printStackTrace();
        }
    }

    synchronized public String pop(){
        String val = "";
        try {
            while (list.size() == 0){
                System.out.println("pop "+Thread.currentThread().getName());
                this.wait();
            }
            val = "" + list.get(0);
            list.remove(0);
            this.notifyAll();
            System.out.println("pop " + list.size());
        } catch (InterruptedException e){
            e.printStackTrace();
        }

        return val;
    }

}


public class P {

    private MyStack myStack;

    public P(MyStack myStack) {
        this.myStack = myStack;
    }

    public void pushService(){
        myStack.push();
    }
}


public class C {

    private MyStack myStack;

    public C(MyStack myStack) {
        this.myStack = myStack;
    }

    public void popService(){
        System.out.println("pop " + myStack.pop());
    }
}



public class C_thread extends Thread{

    private C c;

    public C_thread(C c) {
        this.c = c;
    }

    @Override
    public void run() {
        while (true){
            c.popService();
        }
    }
}

public class P_thread extends Thread{

    private P p;

    public P_thread(P p) {
        this.p = p;
    }

    @Override
    public void run() {
        while (true){
            p.pushService();
        }
    }
}


public class Run {

    public static void main(String[] args) {


//      多消费者 多生产者


        MyStack myStack = new MyStack();

        P p1 = new P(myStack);
        P p2 = new P(myStack);
        P p3 = new P(myStack);
        P p4 = new P(myStack);
        P p5 = new P(myStack);

        P_thread p_thread_1 = new P_thread(p1);
        P_thread p_thread_2 = new P_thread(p2);
        P_thread p_thread_3 = new P_thread(p3);
        P_thread p_thread_4 = new P_thread(p4);
        P_thread p_thread_5 = new P_thread(p5);

        p_thread_1.start();
        p_thread_2.start();
        p_thread_3.start();
        p_thread_4.start();
        p_thread_5.start();


        C c1 = new C(myStack);

        C c2 = new C(myStack);

        C c3 = new C(myStack);

        C c4 = new C(myStack);

        C c5 = new C(myStack);


        C_thread c_thread1 = new C_thread(c1);

        C_thread c_thread2= new C_thread(c2);

        C_thread c_thread3 = new C_thread(c3);

        C_thread c_thread4 = new C_thread(c4);

        C_thread c_thread5 = new C_thread(c5);

        c_thread1.start();
        c_thread2.start();
        c_thread3.start();
        c_thread4.start();
        c_thread5.start();

    }
}




例子:

创建20个线程,10个线程将数据备份到数据库A,10个线程将数据备份到数据库B,备份的过程是交叉进行的

public class DBTools {

    volatile private boolean prevIsA = false;

    synchronized public void backupA(){
        try {
            while (prevIsA == true){
                wait();
            }
            for (int i = 0; i < 5; i++) {
                System.out.println(" * * * * * ");
            }
        } catch (InterruptedException e){
            e.printStackTrace();
        }
        prevIsA = true;
        notifyAll();
    }

    synchronized public void backupB(){
        try {
            while (prevIsA == false){
                wait();
            }
            for (int i = 0; i < 5; i++) {
                System.out.println(" + + + + +");
            }
            prevIsA= false;
            notifyAll();
        } catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}

public class BackupA extends Thread{

    private DBTools dbTools;

    public BackupA(DBTools dbTools) {
        this.dbTools = dbTools;
    }


    @Override
    public void run() {
        dbTools.backupA();
    }
}



public class BackupB extends Thread{

    private DBTools dbTools;

    public BackupB(DBTools dbTools) {
        this.dbTools = dbTools;
    }

    @Override
    public void run() {
        dbTools.backupB();
    }
}




public class Run {

    public static void main(String[] args) {

        DBTools dbTools = new DBTools();

        for (int i = 0; i < 20; i++) {

            BackupB b = new BackupB(dbTools);

            b.start();

            BackupA a = new BackupA(dbTools);

            a.start();

        }

    }
}

发布了189 篇原创文章 · 获赞 58 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/Coder_py/article/details/104028176