package com.Test;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Ticket{
private int number = 30;
Lock lock = new ReentrantLock();
//卖票方法
public void sale(){
lock.lock();
try {
if(number > 0){
System.out.println(Thread.currentThread().getName() + "卖出第" +number-- + "票,剩余" + number+ "张");
}
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
//卖票
public class SaleTicketDemo {
public static void main(String agrs[]){
Ticket ticket = new Ticket();
new Thread(()->{
for(int i = 1; i <= 40;i++){
ticket.sale();
}
},"售票员A").start();
new Thread(()->{
for(int i = 1; i <= 40;i++){
ticket.sale();
}
},"售票员B").start();
new Thread(()->{
for(int i = 1; i <= 40;i++){
ticket.sale();
}
},"售票员C").start();
}
}
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
*
* - {@link Object#wait() Object.wait} with no timeout
* - {@link #join() Thread.join} with no timeout
* - {@link LockSupport#park() LockSupport.park}
*
*
* A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called Object.wait()
* on an object is waiting for another thread to call
* Object.notify() or Object.notifyAll() on
* that object. A thread that has called Thread.join()
* is waiting for a specified thread to terminate.
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
*
* - {@link #sleep Thread.sleep}
* - {@link Object#wait(long) Object.wait} with timeout
* - {@link #join(long) Thread.join} with timeout
* - {@link LockSupport#parkNanos LockSupport.parkNanos}
* - {@link LockSupport#parkUntil LockSupport.parkUntil}
*
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
/*
*
* 1 java.util.ConcurrentModificationException 并发修改异常
*
* 2 解决方法 List: (1)Vector()
* (2)Collection.synchronizedList(new ArrayList())
* (3)CopyOnWriteArrayList()
*
* 解决方法 Set: (1)Collection.synchronizedList(new HashSet())
* (2)CopyOnWriteHashSet()
*
* 解决方法 HashMap: ConcurrentHashMap()
*
* */
public class ListNotSafeDemo {
public static void main(String args[]){
List<String> list = new ArrayList<>();
for(int i = 0;i <= 30; i++){
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
/*
* CopyOnWriteArrayList<>的add()方法
* 1.使用lock方式加锁
* 2.创建一个长度比原数组length长1的新的数组
* 3.将原数组拷贝到新数组,将添加的元素放到数组最后一格
* */
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
package com.Test;
import java.util.concurrent.TimeUnit;
class Phone {
public static void sendEmail() throws Exception {
TimeUnit.SECONDS.sleep(3);
System.out.println("*****sendEmail*****");
}
public static synchronized void sendSMS() throws Exception {
System.out.println("*****sendSMS*****");
}
public void sayHello() throws Exception{
System.out.println("****sayHello****");
}
}
public class Lock8Demo {
/*
* 8lock
*
* 1.标准访问,先打印邮件还是短信
* 2.邮件暂停4s,先打印邮件还是短信
* 3.新增普通sayHello()方法,先打印哪个
* 4.两部phone,先打印哪个 短信 邮件
* 5.两个静态同步方法,同意一部手机,请问先打印短息还是邮件
* 6.两个静态同步方法,2部手机,请问先打印邮件还是短信
* 7.1个静态同步方法,1个普通同步方法,同意一部手机,请问先打印邮件还是短信
* 8.一个静态同步方法,一个普通同步方法,同意一部手机,先打印邮件还是短信
*
* 锁的是当前对象this,被锁定后,某一时刻内,只能有唯一一个线程去访问这些synchronized方法
*
* 同步方法与同步锁无关
* 换成两个对象后,不是同一把锁,情况改变,换成静态同步方法后,锁的是当前类,情况又改变
*
* synchronized实现同步的基础:Java中的每一个对象都可以作为锁
* (1)对于普通同步方法,锁的是当前实例对象,锁的是当前对象this
* (2)对于同步方法块,锁是synchonized括号里配置的对象
* (3)对于静态同步方法,锁的是当前类的class对象
* */
public static void main(String args[]) throws Exception{
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(()->{
try {
phone.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
try {
phone.sendSMS();
// phone.sayHello();
// phone2.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
},"B").start();
}
}
package com.Test;
class Aicondition{
private int number = 0;
public synchronized void increment() throws Exception{
while(number != 0){
this.wait();
}
number++;
System.out.println(Thread.currentThread().getName()+"\t" + number);
this.notifyAll();
}
public synchronized void decrement() throws Exception{
while(number == 0){
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName()+"\t" + number);
this.notifyAll();
}
}
/*
*
* 多个线程操作一个初始值为0的变量,使其交替打印0和1
* 1高内聚、低耦合,线程操作资源类
* 2判断、工作、通知
* 3防止虚假唤醒 多线程中的判断要使用while代替if重新做条件判断
*
**/
public class ProducerConsumerDemo {
public static void main(String args[]){
Aicondition aicondition = new Aicondition();
new Thread(()->{
for(int i = 1;i <= 10; i++){
try {
aicondition.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for(int i = 1;i <= 10; i++){
try {
aicondition.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(()->{
for(int i = 1;i <= 10; i++){
try {
aicondition.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(()->{
for(int i = 1;i <= 10; i++){
try {
aicondition.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"D").start();
}
}
package com.Test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class ShareData{
private int number = 1;
private Lock lock = new ReentrantLock();
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
public void print5(){
lock.lock();
try{
//1.判断
while (number != 1) {
c1.await();
}
//2.工作
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
number = 2;
c2.signal();
} catch (Exception e){
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print10(){
lock.lock();
try{
//1.判断
while (number != 2) {
c2.await();
}
//2.工作
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
number = 3;
c3.signal();
} catch (Exception e){
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print15(){
lock.lock();
try{
//1.判断
while (number != 3) {
c3.await();
}
//2.工作
for (int i = 1; i <= 15; i++) {
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
number = 1;
c1.signal();
} catch (Exception e){
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
/*
* 多线程之间按顺序调用,实现A->B->C
*
*
*
* */
public class ConditionDemo {
public static void main(String args[]){
ShareData shareData = new ShareData();
new Thread(()->{
for(int i = 0; i < 5; i++){
shareData.print5();
}
},"A").start();
new Thread(()->{
for(int i = 0; i < 5; i++){
shareData.print10();
}
},"B").start();
new Thread(()->{
for(int i = 0; i < 5; i++){
shareData.print15();
}
},"C").start();
}
}
package com.Test;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class MyThread implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("*****COME IN CALL METHOD()*****");
return 1024;
}
}
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask futureTask = new FutureTask(new MyThread());
new Thread(futureTask,"A").start();
Integer result = (Integer)futureTask.get();
System.out.println(result);
}
}
当执行足够的次数后,才能继续执行
import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
//设置次数为6次
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
//计数,执行一次改行代码,计数一次
countDownLatch.countDown();
System.out.println(Thread.currentThread().getName() + "\t离开教室");
},String.valueOf(i)).start();
}
//等待,执行足够的次数后,才能执行后续代码(设定次数为6次)
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "\t关门");
}
public static void closeDoor(){
for(int i = 1; i <= 6; i++){
new Thread(()->{
System.out.println(Thread.currentThread().getName() + "\t离开教室");
},String.valueOf(i)).start();
}
}
}
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
public static void main(String[] args){
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("人齐开会");
});
for(int i = 1; i <= 7; i++){
new Thread(()->{
System.out.println(Thread.currentThread().getName() +"\t到场");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/*
* 信号量主要用于两个目的:
* 1.用于多个共享资源的互斥作用
* 2.用于并发线程数的控制
*
* */
public class SemaphoreDemo {
public static void main(String[] args){
//模拟资源类,有三个空车位
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"\t抢占到了车位");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName()+"\t离开了车位");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
},String.valueOf(i)).start();
}
}
}
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
class MyCache{
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private volatile Map<String,Object> map = new HashMap<>();
public void put(String key,Object value) throws InterruptedException {
readWriteLock.writeLock().lock();
try{
System.out.println(Thread.currentThread().getName() + "\t 写入数据" + key);
TimeUnit.SECONDS.sleep(1);
map.put(key,value);
System.out.println(Thread.currentThread().getName() + "\t 写入完成" + key);
} catch (Exception e) {
e.printStackTrace();
} finally {
readWriteLock.writeLock().unlock();
}
}
public void get(String key) throws InterruptedException {
readWriteLock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "\t 读取数据");
TimeUnit.SECONDS.sleep(1);
map.get(key);
System.out.println(Thread.currentThread().getName() + "\t 读取数据");
} catch (Exception e) {
e.printStackTrace();
} finally {
readWriteLock.readLock().unlock();
}
}
}
/*
* 多个线程同时读取一个资源类没有问题,为了满足并发量需求,读取共享资源可以同时进行
* 但是如果有一个线程写共享资源,就不应该再有其他线程对该资源读或写
*
* 读-读 共存
* 读-写 不共存
* 写-写 不共存
* */
public class ReadWriteLockDemo {
public static void main(String[] args){
MyCache myCache = new MyCache();
for(int i = 1; i <= 5; i++){
final int tempInt = i;
new Thread(()->{
try {
myCache.put(tempInt+"",tempInt+"");
} catch (InterruptedException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
for(int i = 1; i <= 5; i++){
final int tempInt = i;
new Thread(()->{
try {
myCache.get(tempInt+"");
} catch (InterruptedException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
/*
* 当队列是空的,从队列中获取元素的操作将会被堵塞
* 当队列是满的,从队列中添加元素的操作将会被阻塞
*
* BlockingQueue核心方法
* 插入: add() 队满时异常IllegalStateException
* offer() 队满时插入失败,返回false
* put() 队满时阻塞,直到插入成功
* offer(e,time,TimeUnit) 队满时,等待一定时间,如果插入成功返回true,
* 如果仍然队满,返回false
*
* 移除: remove() 空队时异常NoSuchElementException
* poll() 空队移除时返回null
* take() 空队时阻塞,直到拿到元素
* poll(time,TimeUnit) 队时空,等待一定时间,如果读取成功返回元素,
* 如果仍然队空,返回null
*
* 检查:element() 查看队首元素
* */
public class BlockingQueueDemo {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
/*
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
*/
/*
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.element());
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("a"));*/
/*
blockingQueue.put("a");
blockingQueue.put("a");
blockingQueue.put("a");
blockingQueue.put("a");*/
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("a", 3, TimeUnit.SECONDS));
}
}
尚硅谷JUC课程学习笔记