public class Demo02 {
public static void main(String[] args) {
Data data = new Data();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "A").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "B").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "C").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "D").start();
}
}
class Data {
private int num = 0;
public synchronized void increment() throws InterruptedException {
//将if改用为while以防止虚假唤醒
while (num != 0) {
this.wait();
}
num++;
System.out.println(Thread.currentThread().getName() + "=>" + num);
this.notifyAll();
}
public synchronized void decrement() throws InterruptedException {
while (num == 0) {
this.wait();
}
num--;
System.out.println(Thread.currentThread().getName() + "=>" + num);
this.notifyAll();
}
}
package cn.juc.unsafe;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author ikart
* @date 2021年04月17日9:48
*/
public class SafeTest {
public static void main(String[] args) {
/**
* 解决list集合不安全
* 方式一:List<String> list = new Vector<>();
* 方式二:List<String> list = Collections.synchronizedList(new ArrayList<>());\\
* 方式三:List<String> list = new CopyOnWriteArrayList<>(); 使用JUC
*/
List<String> list = new CopyOnWriteArrayList<>();
for (int i = 0; i < 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(1, 5));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
package cn.juc.unsafe;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* @author ikart
* @date 2021年04月17日10:21
*/
public class SetUnsafe {
public static void main(String[] args) {
// Set<String> set = new HashSet<>(); //线程不安全的
// Set<String> set = Collections.synchronizedSet(new HashSet<>()); 使用集合工具保证线程安全
Set<String> set = new CopyOnWriteArraySet<>(new HashSet<>()); 使用JUC保证线程安全
for (int i = 0; i < 30; i++) {
new Thread(()->{
set.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(set);
},String.valueOf(i)).start();
}
}
}
package cn.juc.callable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* @author ikart
* @date 2021年04月17日15:08
*/
public class CallableTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Phone phone = new Phone();
//FutureTask适配器
FutureTask futureTask = new FutureTask<>(phone);
new Thread(futureTask,"A").start();
//结果会被缓存,效率高
new Thread(futureTask,"B").start();
//这个get可能会导致线程阻塞,要把它放到最后执行,或者使用异步通信的方式解决
Integer o = (Integer)futureTask.get();
System.out.println(o);
}
}
class Phone implements Callable{
@Override
public Integer call() throws Exception {
System.out.println("call()"+ Thread.currentThread().getName());
return 657;
}
}
运行结果:
call()A
657
此时开启了两条线程,发现运行的是线程A,证明了结果被缓存了。
package cn.juc.common_util;
import java.util.concurrent.CountDownLatch;
/**
* 一个减法技术器的测试案例
* @author ikart
* @date 2021年04月17日15:54
*/
public class CountDownLatchTest {
public static void main(String[] args) throws Throwable {
//减法计数器,给定一个数值,依次往下减
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(()->{
System.out.println("Go out "+Thread.currentThread().getName());
countDownLatch.countDown();
},String.valueOf(i)).start();
}
//当减完后执行后面的操作
countDownLatch.await();
System.out.println("Close Door");
}
}
package cn.juc.common_util;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* @author ikart
* @date 2021年04月18日11:32
*/
public class CyclicBarrierTest {
public static void main(String[] args) {
//当计数器到设定值时,开启一条新线程
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("成功召唤神龙");
});
for (int i = 1; i <= 7; i++) {
//注意局部变量i的作用域
final int temp = i;
new Thread(() -> {
System.out.println(Thread.currentThread().getName()+"获得第"+ temp +"颗龙珠");
try {
//每执行一次,执行+1(从0开始)
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
package cn.juc.common_util;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* @author ikart
* @date 2021年04月18日13:09
*/
public class SemaphoreTest {
public static void main(String[] args) {
//一次最多同时授权许可证
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 9; i++) {
final int temp = i;
new Thread(()->{
try {
//获得许可证
semaphore.acquire();
System.out.println("第"+Thread.currentThread().getName()+"车进来了");
TimeUnit.SECONDS.sleep(3);
System.out.println("第"+Thread.currentThread().getName()+"车走了");
//释放许可证
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}