java核心-多线程-零碎知识收集

1.不能使用Integer作为并发锁

    原因:synchronized(Integer)时,当值发生改变时,基本上每次锁住的都是不同的对象实例,想要保证线程安全,推荐使用AtomicInteger之类会更靠谱。使用System.identityHashCode(obj)可以得到根据物理地址算出的hash值。

2.notify()和wait()新认知

    notify()是唤醒等待线程,不唤醒的话,即使锁已经空出来了,线程也不会知道去获取;
    wait()是放弃当前锁,进入睡眠状态,下次唤醒执行开始的地方;

3.两个线程交替打印奇偶数,打印对象必须使用AtomicInteger

package example;

import java.util.concurrent.atomic.AtomicInteger;

public class Exercise {

    static volatile Integer num = new Integer(0);   //这里即使是volatile也不行,必须使用AtomicInteger

    public static void main(String[] args){

        Object o1 = new Object();
        Thread t1 = new MyThread(num,true,o1);
        Thread t2 = new MyThread(num,false,o1);
        t1.start();
        t2.start();

    }

    public static class MyThread extends Thread{

        public Integer num;

        public boolean flag;

        public Object o1;


        public MyThread(Integer num, boolean flag, Object o1){
            this.num = num;
            this.flag = flag;
            this.o1 = o1;
        }

        @Override
        public void run(){
            System.out.println(getName() + "线程启动:" + flag);
            while (true){
                if(flag){
                    synchronized (o1){
                        if(num > 100){
                            System.out.println(getName() + " over");
                            break;}
                        if(num % 2 == 0){

                            System.out.println("打印偶数的线程,打印了:"+num);
                            num++;
                            o1.notify();
                            try {
                                o1.wait();
                            }catch (Exception e){}
                        }
                    }
                }
                if(!flag){
                    synchronized (o1){
                        if(num % 2 != 0){
                            if(num > 100){
                                System.out.println(getName() + " over");
                                break;
                            }
                            num++;
                            o1.notify();
                            try {
                                o1.wait();
                            }catch(Exception e){
                            }
                        }
                    }
                }
            }
        }
    }
}
总结,在Integer值发生变化时,会生成新的对象
package com.thread;

import javax.swing.*;
import java.util.concurrent.atomic.AtomicInteger;

public class JiaoTiDaYinTest {

    public static void main(String[] args) {
        JiThread jiThread = new JiThread();
        OThread oThread = new OThread();
        AtomicInteger atomicInteger = new AtomicInteger(0);
        jiThread.setNum(atomicInteger);
        oThread.setNum(atomicInteger);
        jiThread.start();
        oThread.start();

    }

    public static class JiThread extends Thread {
        public AtomicInteger getNum() {
            return num;
        }

        public void setNum(AtomicInteger num) {
            this.num = num;
        }

        private AtomicInteger num;

        @Override
        public void run() {
            while (true) {
                synchronized (num) {
                    int get = num.get();
                    if (num.get() > 100) {
                        num.notify();
                        break;
                    }
                    if (get % 2 == 0) {
                        System.out.println("ji:" + get);
                    } else {
                        System.out.println("奇数线程:" + num.get());
                        num.incrementAndGet();
                    }
                    try {
                        num.notify();
                        num.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static class OThread extends Thread {
        public AtomicInteger getNum() {
            return num;
        }

        public void setNum(AtomicInteger num) {
            this.num = num;
        }

        private AtomicInteger num;

        @Override
        public void run() {
            while (true) {
                synchronized (num) {
                    int get = num.get();
                    if (num.get() > 100) {
                        num.notify();
                        break;
                    }
                    if (get % 2 != 0) {
                        System.out.println("ou:" + get);
                    } else {
                        System.out.println("偶数线程:" + num.get());
                        num.getAndIncrement();
                    }
                    try {
                        num.notify();
                        num.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

posted on 2019-06-01 16:34  火枪  阅读(130)  评论(0编辑  收藏  举报