某个类在整个进程的运行过程中,只允许有一个对象
public class HungryMan {
//一开始就初始化
private static HungryMan instance = new HungryMan();
private HungryMan() {
}
public static HungryMan getInstance() {
return instance;
}
static class MyThread extends Thread {
@Override
public void run() {
HungryMan ins1 = HungryMan.getInstance();
System.out.println(ins1);
}
}
public static void main(String[] args) {
//单线程环境下
// singleton.HungryMan ins1 = singleton.HungryMan.getInstance();
// singleton.HungryMan ins2 = singleton.HungryMan.getInstance();
// singleton.HungryMan ins3 = singleton.HungryMan.getInstance();
//
// System.out.println(ins1 == ins2); //true
// System.out.println(ins2 == ins3); //true
//多线程环境下也是同一个对象
MyThread[] threads = new MyThread[20];
for (int i = 0; i < 20; i++) {
threads[i] = new MyThread();
}
for (int i = 0; i < 20; i++) {
threads[i].start();
}
}
}
public class LazyMan {
private static volatile LazyMan instance = null;
private LazyMan() {
}
//单线程版,多线程环境下可能会出现问题
// public static LazyMan getInstance() {
// if (instance == null) {
// instance = new LazyMan();
// }
// return instance;
// }
//法一二三四都是多线程版
//法一:
public static LazyMan getInstance1() {
synchronized (LazyMan.class) {
if (instance == null) {
instance = new LazyMan();
}
}
return instance;
}
// //法二:
// public synchronized static LazyMan getInstance2() {
// if (instance == null) {
// instance = new LazyMan();
// }
// return instance;
// }
//
// //法三:
// private static Object lock = new Object(); //在方法外面
// public static LazyMan getInstance3() {
// synchronized (lock) {
// if (instance == null) {
// instance = new LazyMan();
// }
// }
// return instance;
// }
//二次判断-性能高
public static LazyMan getInstance4() {
if (instance == null) {
synchronized (LazyMan.class) {
if (instance == null) {
instance = new LazyMan(); //有重排序问题,加入volatile
}
}
}
return instance;
}
static class MyThread extends Thread {
@Override
public void run() {
LazyMan ins = LazyMan.getInstance4();
System.out.println(ins);
}
}
public static void main(String[] args) {
// //单线程
// LazyMan ins1 = LazyMan.getInstance();
// LazyMan ins2 = LazyMan.getInstance();
// LazyMan ins3 = LazyMan.getInstance();
// System.out.println(ins1 == ins2); //true
// System.out.println(ins2 == ins3); //true
//多线程环境下
MyThread[] threads = new MyThread[20];
for (int i = 0; i < 20; i++) {
threads[i] = new MyThread();
}
for (int i = 0; i < 20; i++) {
threads[i].start();
}
}
}
高效的多线程版本
为什么synchronized
为什么二次判断
为什么volatile
自己实现
public class MyArrayBlockingQueue {
int[] array = new int[10];
int front = 0; //只有消费者会改变
int rear = 0; //只有生产者会改变
int size = 0; //共享且会被修改
synchronized void put(int value) throws InterruptedException {
while (size == array.length) {
wait();
}
array[rear] = value;
rear = (rear + 1) % array.length;
size++;
System.out.println(size);
notifyAll();
}
synchronized void put2(int value) throws InterruptedException {
if (size == array.length) {
this.wait();
}
array[rear] = value;
rear = (rear + 1) % array.length;
size++;
System.out.println(size);
notify();
}
synchronized int take() throws InterruptedException {
if (size == 0) {
this.wait();
}
int t = array[front];
front = (front + 1) % array.length;
size--;
notify();
return t;
}
static MyArrayBlockingQueue queue = new MyArrayBlockingQueue();
static class Producer extends Thread {
@Override
public void run() {
int j = 0;
while (true) {
try {
queue.put(j);
j++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
//多个生产者和多个消费者情况下
MyBlockingArrayQueue.Producer producer1 = new MyBlockingArrayQueue.Producer();
MyBlockingArrayQueue.Producer producer2 = new MyBlockingArrayQueue.Producer();
MyBlockingArrayQueue.Producer producer3 = new MyBlockingArrayQueue.Producer();
producer1.start();
producer2.start();
producer3.start();
Thread.sleep(2*1000);
while (true) {
queue.take();
}
}
}
使用
public class BlockingQueueDemo {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> q1 = new ArrayBlockingQueue(15);
BlockingQueue<String> q2 = new LinkedBlockingDeque<>();
BlockingQueue<String> q3 = new PriorityBlockingQueue<>();
q1.put("");
String take = q1.take();
System.out.println(take);
}
}
自己实现
import java.util.concurrent.TimeUnit;
//定时器,10秒后打印一个happy
public class SimpleTimer {
interface SimpleTimerTask {
void run();
}
//这个线程先 sleep delay时间后,再去执行任务
static class Worker extends Thread {
long delay;
SimpleTimerTask task;
Worker(SimpleTimerTask task, long delay) {
this.task = task;
this.delay = delay;
}
@Override
public void run() {
try {
Thread.sleep(delay);
task.run();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void schedule(SimpleTimerTask task, long delay) {
Worker worker = new Worker(task, delay);
worker.start();
}
static class MyTask implements SimpleTimerTask {
@Override
public void run() {
System.out.println("happy");
}
}
public static void main(String[] args) throws InterruptedException {
SimpleTimer timer = new SimpleTimer();
MyTask task = new MyTask();
timer.schedule(task, 10*1000);
int i = 0;
while (true) {
System.out.println(i++);
TimeUnit.SECONDS.sleep(1);
}
}
}
使用
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
public class TimerDemo {
static class MyTask extends TimerTask {
@Override
public void run() {
System.out.println("已经是 10 秒中后了");
}
}
public static void main(String[] args) throws InterruptedException {
TimerTask task = new MyTask();
Timer timer = new Timer();
timer.schedule(task, 10*1000);
int i = 0;
while (true) {
System.out.println(i++);
TimeUnit.SECONDS.sleep(1);
}
}
}