单例模式:常用的两种模式:饿汉模式 懒汉模式,但这两种模式在多线程应用场景并不安全
为了适用于多线程,保障线程安全,用下面两种:double check instance、static inner class
package thread;
/**
* 单例模式,保障线程安全
* static inner class
* 静态内部类形式
*/
public class SingleInner {
private static class Singleton{
private static Singleton single = new Singleton();
}
public static Singleton getInstance(){
return Singleton.single;
}
}
public class Singleton{
//私有静态实例,防止被引用
private static Singleton instance = null;
//私有构造方法,防止被实例化
private Singleton(){
}
private static synchronized void syncInit(){
if(instance == null){
instance = new Singleton();
}
}
public static Singleton getInstance(){
if(instance == null){
syncInit();
}
return instance;
}
}
并发类:Queue、concurrentMap、LinkedBlockingQueue、CopyOnWrite
package queue;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* ConcurrentLinkedQueue非阻塞的,性能高,高并发
* 先进先出,头是最先的,尾是最近的,不允许有null值
* add() offer()加入元素,在ConcurentLinkedQueue里没区别
* poll() peek() 取头元素,前者删除元素,后者不删
*/
public class UseConcurrentQueue {
public static void main(String[] args) {
ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
q.add("a");
q.add("b");
q.add("c");
q.add("d");
q.offer("e");
q.offer("f");
System.out.println(q.size());
System.out.println(q.poll());
System.out.println(q.size());
System.out.println(q.peek());
System.out.println(q.size());
}
}
package queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
/**
* BlockingQueue:阻塞的
* ArrayBlockingQueue:基于数组的,有界的
* linkedBlockingQueue:无界的,在初始化时,给定长度,则是有界的,不给定长度,则是无界的
* SynchronousQueue:没有容量的队列,take()方法会进行阻塞,执行过take后,可以进行add,直接add会报错,因为没容量
*
*/
public class UseBlockingQueue {
public static void main(String[] args) throws Exception{
//ArrayBlockingQueue
ArrayBlockingQueue aq = new ArrayBlockingQueue(5);
aq.add("a");
aq.add("b");
aq.put("c");
aq.put("d");
aq.offer("e");
aq.offer("f");
System.out.println("ArrayBlockingQueue:"+aq);
//linkedBlockingQueue
LinkedBlockingQueue lq = new LinkedBlockingQueue<>();
lq.add("a");
lq.add("b");
lq.put("c");
lq.put("d");
lq.offer("e");
lq.offer("f");
System.out.println("LinkedBlockingQueue无界:"+lq);
LinkedBlockingQueue lq2 = new LinkedBlockingQueue<>(4);
lq2.add("a");
lq2.add("b");
lq2.put("c");
lq2.put("d");
lq2.offer("e");
lq2.offer("f");
System.out.println("LinkedBlockingQueue有界:"+lq2);
//synchronousQueue
final SynchronousQueue sq = new SynchronousQueue<>();
//sq.add("a"); //会报错java.lang.IllegalStateException: Queue full
Thread t1 = new Thread(new Runnable(){
@Override
public void run() {
try {
sq.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
sq.add("a");
System.out.println("SynchronousQueue:"+sq);
}
});
t2.start();
}
}
package queue;
import java.util.concurrent.PriorityBlockingQueue;
import queue.priority.Task;
/**
* PriorityBlockingQueue:优先级队列
* 队列里的元素必须继承comparable接口,并实现方法
* 当对队列进行take操作是,队列会根据优先级排序(不遵循先进先出)
*
*/
public class UsePriorityBlockingQueue {
public static void main(String[] args) throws Exception{
PriorityBlockingQueue pq = new PriorityBlockingQueue();
Task t1 = new Task();
t1.setId(1);
t1.setName("任务1");
Task t2 = new Task();
t2.setId(4);
t2.setName("任务2");
Task t3 = new Task();
t3.setId(3);
t3.setName("任务3");
pq.add(t1);
pq.add(t2);
pq.add(t3);
System.out.println("容器:"+pq.toString());
System.out.println(pq.take().getId());
System.out.println("容器:"+pq.toString());
System.out.println(pq.take().getId());
System.out.println(pq.take().getId());
}
}
package queue.priority;
public class Task implements Comparable{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(Task o) {
return this.id > o.id ? 1 : (this.id > o.id ? -1 : 0);
}
public String toString(){
return this.id + "," + this.name;
}
}
容器:[1,任务1, 4,任务2, 3,任务3]
1
容器:[3,任务3, 4,任务2]
3
4
package queue;
import java.util.concurrent.DelayQueue;
import queue.delay.Wangmin;
/**
* DelayQueue:延迟队列
* 元素必须实现delayed接口
* 元素必须到达延迟时间时,才会被取出
*/
public class UseDelayQueue implements Runnable{
DelayQueue dq = new DelayQueue();
public void shangji(int id, String name, int money){
Wangmin wm = new Wangmin(id,name,1000*money+System.currentTimeMillis());
dq.add(wm);
System.out.println("网民:"+name+"开始上机,上机时间"+money+"秒");
}
public void xiaji(Wangmin wm){
System.out.println("网民:"+wm.getName()+"下机。。。");
}
@Override
public void run() {
while(true){
try {
Wangmin wm = dq.take();
xiaji(wm);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
UseDelayQueue udq = new UseDelayQueue();
Thread t = new Thread(udq);
t.start();
udq.shangji(1,"张三",1);
udq.shangji(2,"李四",10);
udq.shangji(3,"王五",5);
}
}
package queue.delay;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
* 网民
* 实现了Delayed接口
* 需要实现getDelay、compareTo方法
*/
public class Wangmin implements Delayed{
private int id;
private String name;
private long endtime;
private TimeUnit timeUnit = TimeUnit.SECONDS;//时间单位,秒
//构造方法
public Wangmin(int id, String name, long endtime){
this.id=id;
this.name = name;
this.endtime = endtime;
}
@Override
public int compareTo(Delayed delay) {
Wangmin w = (Wangmin)delay;
return this.getDelay(this.timeUnit) > w.getDelay(this.timeUnit) ? 1 : 0;
}
@Override
public long getDelay(TimeUnit arg0) {
return endtime - System.currentTimeMillis();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getEndtime() {
return endtime;
}
public void setEndtime(long endtime) {
this.endtime = endtime;
}
}