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();
}
}
}
}
}
}