在前锋“逆战”学习第30天
课堂案例
阻塞队列
public class TestQueue {
public static void main(String[] args) {
// Queue<String> q = new
// 列表,尾部添加(指定下标)
// 链表,头尾添加
// 队列,FIFO
// 如果要强制LinkedList只遵循队列的规则!
// Queue<String> link = new LinkedList<String>(); //遵循队列规则的链表
LinkedList<String> link = new LinkedList<String>();
link.offer("A");
link.offer("B");
link.offer("C");
// 用列表的方式打乱了FIFO队列的规则
// link.add(0,"D");
// 强制LinkedList后,不能调用带有下标的add方法
System.out.println(link.peek());// 队列中的第一个元素!
// 严格遵守了队列的规则,且是线程安全的,采用了CAS交换算法
Queue<String> q = new ConcurrentLinkedQueue<String>();
// 1.抛出异常的 2.返回结果的
q.offer("A");
q.offer("B");
q.offer("C");
q.poll();// 删除表头
System.out.println(q.peek());// 获得表头
// 手动固定队列上限
BlockingQueue<String> bq = new ArrayBlockingQueue<String>(3);
// 无界队列 最大有 Integer.MAX_VALUE
BlockingQueue<String> lbq = new LinkedBlockingQueue<String>();
}
}
--------------------------------------------------------------------------
读写锁
public class TestReadWriteLock {
public static void main(String[] args) {
Student stu = new Student();
ExecutorService es = Executors.newFixedThreadPool(20);
WriteTask1 write = new WriteTask1(stu);
ReadTask read = new ReadTask(stu);
long start = System.currentTimeMillis();
es.submit(write);
es.submit(write);
for (int i = 1; i <= 18; i++) {
es.submit(read);
}
es.shutdown();
while (true) {
System.out.println("结束了吗?");
if (es.isTerminated() == true) {
break;
}
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
class WriteTask1 implements Callable {
Student stu;
public WriteTask1(Student stu) {
this.stu = stu;
}
public Object call() throws Exception {
stu.setAge(100);
return null;
}
}
class ReadTask implements Callable {
Student stu;
public ReadTask(Student stu) {
this.stu = stu;
}
public Object call() throws Exception {
stu.getAge();
return null;
}
}
class Student {
private int age;
// Lock lock = new ReentrantLock();
ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock();
ReadLock read = rrwl.readLock();
WriteLock write = rrwl.writeLock();
public int getAge() {
read.lock();
try {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return this.age;
} finally {
read.unlock();
}
}
public void setAge(int age) {
write.lock();
try {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.age = age;
} finally {
write.unlock();
}
}
}
--------------------------------------------------------------------------
同步锁
public class TestCollectionForSyn {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();// 0x112233
List<String> safeList = Collections.synchronizedList(list);
// 和普通集合应用无差别
safeList.add("A");// SynchronizedList里的add方法。该方法里加了个锁
safeList.add("B");
safeList.add("C");
safeList.remove(1);
safeList.get(1);
Set<String> sets = new HashSet<String>();
Set<String> newSet = Collections.synchronizedSet(sets);
newSet.add("A");
newSet.add("B");
newSet.add("C");
for (String s : newSet) {
System.out.println(s);
}
}
}
--------------------------------------------------------------------------
锁
public class TestLock {
public static void main(String[] args) {
Test obj = new Test();
Thread t1 = new Thread(new MyTask(obj));
Thread t2 = new Thread(new MyTask2(obj));
t1.start();
t2.start();
}
}
class Test {
Lock lock = new ReentrantLock();
public void method() {
// 此处获得锁
System.out.println(Thread.currentThread().getName() + "进入到上锁的方法");
try {
lock.lock();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} finally {
// 此处释放锁
System.out.println(Thread.currentThread().getName() + "退出到上锁的方法");
lock.unlock();
}
}
}
class MyTask implements Runnable {
Test obj;
public MyTask(Test obj) {
this.obj = obj;
}
public void run() {
obj.method();
}
}
class MyTask2 implements Runnable {
Test obj;
public MyTask2(Test obj) {
this.obj = obj;
}
public void run() {
obj.method();
}
}
--------------------------------------------------------------------------
读写锁集合
public class TestCopyOnWirte {
public static void main(String[] args) {
// 写有锁, 读无锁的集合。
CopyOnWriteArrayList<String> alist = new CopyOnWriteArrayList<String>();
// 写操作 有锁
alist.add("A");// 都将底层数组做了一次复制,写的是新数组,完成赋值后,再将新数组替换掉旧数组!
alist.add("B");// 每调用一次,底层方法扩容一次!
// 读操作 无锁
alist.get(1);// 读的是写操作完成之前的旧数组!写完之后,才能读到的新数组的新值
// 无序、无下标、不允许重复
CopyOnWriteArraySet<String> aset = new CopyOnWriteArraySet<String>();
// 写操作 表面使用的是add方法,底层实际是用的CopyOnWriteArrayList的 addIfAbsent()来判断要插入的新值是否存在
aset.add("A");
aset.add("B");
aset.add("C");
for (String s : aset) {
System.out.println(s);
}
HashMap<String, String> maps = new HashMap<String, String>();
// 分段锁设计 Segment JDK1.7的做法
// CAS交换算法和同步锁 同步锁锁的是表头对象,拿到锁的对象要先做节点遍历。查看有没有相同的key,相同覆盖,不同,则挂在最后一个节点的next上
// JDK1.8的做法
ConcurrentHashMap<String, String> ch = new ConcurrentHashMap<String, String>();
ch.put("A", "蓝轩");
ch.keySet();
}
}