项目主体源码可以从ConcurrenceBasics获得,喜欢的朋友可以点个star~。
/**
* 有N张火车票,每张票都有一个编号,同时有10个窗口对外售票。
* 分析下面的程序可能会产生哪些问题?
* 重复销售?超量销售?
* 问题:有可能卖重复,remove也不是原子性的。
*/
public class TicketSeller1 {
static List<String> tickets = new ArrayList<>();
static {
for (int i = 0; i < 10000; i++)
tickets.add("票编号:" + i);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++){
new Thread(()->{
while (tickets.size() > 0){
System.out.println("销售了--" + tickets.remove(0));
}
}).start();
}
}
}
/**
* 有N张火车票,每张票都有一个编号,同时有10个窗口对外售票。
* 分析下面的程序可能会产生哪些问题?
* 问题:判断与操作分离了。
*/
public class TicketSeller2 {
static Vector<String> tickets = new Vector<>();
static {
for (int i = 0; i < 1000; i++)
tickets.add("票编号:" + i);
}
public static void main(String[] args) {
for(int i = 0; i < 10; i++){
new Thread(()->{
while (tickets.size() > 0){
//这部分可能会会被打断,实际开发中也有可能出现,所以需谨慎
try {
TimeUnit.SECONDS.sleep(10);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("销售了--" + tickets.remove(0));
}
}).start();
}
}
}
/**
* 有N张火车票,每张票都有一个编号,同时有10个窗口对外售票。
* 分析下面的程序可能会产生哪些问题?
* 运行结果:运行结果没有问题,相当于把判断与操作加到一个锁里面,属于一个原子。但是效率不高。
*/
public class TicketSeller3 {
static List<String> tickets = new LinkedList<>();
static {
for (int i = 0; i < 1000; i++)
tickets.add("票编号:" + i);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++){
new Thread(()->{
while (true){
synchronized (tickets){
if(tickets.size() <= 0) break;
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("销售了--" + tickets.remove(0));
}
}
}).start();
}
}
}
/**
* 有N张火车票,每张票都有一个编号,同时有10个窗口对外售票。
* 运行结果:效率高,这里下面判断与操作并不是原子性,但是为什么没有问题,因为这里判断以后没有对值做修改操作。
*/
public class TicketSeller4 {
static Queue<String> tickets = new ConcurrentLinkedQueue<>();
static {
for (int i = 0; i < 1000; i++)
tickets.add("票编号:" + i);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++){
new Thread(()->{
while (true){
String s = tickets.poll();
if(s == null) break;
else System.out.println("销售了--" + s);
}
}).start();
}
}
}
/**
* 有界队列
*/
public class ArrayBlockingQueueTs {
static BlockingQueue<String> strs = new ArrayBlockingQueue<>(10);
//static Random r = new Random();
public static void main(String[] args) throws InterruptedException {
for(int i = 0; i < 10; i++){
strs.put("a" + i);
}
//会一直等待,等待strs空一位然后添加进去,满了会阻塞
//strs.put("aaa");
//会报异常
//strs.add("aaa");
//不会报异常,因为它会有一个boolean返回值
//strs.offer("aaa");
//这里意思是一秒钟后,没有添加成功就不往里面继续加了
//strs.offer("aaa", 1, TimeUnit.SECONDS);
System.out.println(strs);
}
}
/**
* 无界队列
*/
public class LinkedBlockingQueueTs {
static BlockingQueue<String> strs = new LinkedBlockingQueue<>();
static Random r = new Random();
public static void main(String[] args) {
new Thread(()->{
for(int i = 0; i < 100; i++){
try {
strs.put("a" + i); //如果满了,就会等待
TimeUnit.MILLISECONDS.sleep(r.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "p1").start();
for (int i = 0; i < 5; i++){
new Thread(()->{
for (;;){
try {
System.out.println(Thread.currentThread().getName() + " tack - " + strs.take());//如果空了,则生成
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "c" + i).start();
}
}
}
/**
* 并发容器,效率对比
*/
public class ConcurrentMap {
public static void main(String[] args) {
//ConcurrentHashMap这里就是把锁分成16段,每段执行的时候加上那一段锁,所以效率相对比较高
Map<String, String> map = new ConcurrentHashMap<>();
//Map map = new ConcurrentSkipListMap<>();
//Map map = new Hashtable<>();
//Map map = new HashMap<>();
Random r = new Random();
Thread[] ths = new Thread[100];
//门闩计数器
CountDownLatch latch = new CountDownLatch(ths.length);
long start = System.currentTimeMillis();
for(int i = 0; i < ths.length; i++){
ths[i] = new Thread(()->{
for (int j = 0; j < 10000; j++)
map.put("a" + r.nextInt(100000), "a" + r.nextInt(100000));
latch.countDown();
});
}
Arrays.asList(ths).forEach(t->t.start());
try {
latch.await();
}catch (InterruptedException e){
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
/**
* 队列
*/
public class ConcurrentQueue {
public static void main(String[] args) {
Queue<String> strs = new ConcurrentLinkedQueue<>();
for (int i = 0; i < 10; i++){
strs.offer("a" + i);
}
//size = 10
System.out.println(strs);
System.out.println(strs.size());
//size = 9,poll是拿出来删了
System.out.println(strs.poll());
System.out.println(strs.size());
//size = 9,peek是拿出来不删
System.out.println(strs.peek());
System.out.println(strs.size());
//还有双向队列
}
}
/**
* 写时复制容器copy on write
* 多线程环境下,写时效率低,读时效率高
* 适合写少读多的环境
*/
public class CopyOnWriteList {
public static void main(String[] args) {
List<String> lists =
//new ArrayList<>();//这个会出并发问题!
//new Vector<>();
new CopyOnWriteArrayList<>();
Random r = new Random();
Thread[] ths = new Thread[100];
for(int i = 0; i < ths.length; i++){
Runnable task = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) lists.add("a" + r.nextInt(10000));
}
};
ths[i] = new Thread(task);
}
runAndComputeTime(ths);
System.out.println(lists.size());
}
static void runAndComputeTime(Thread[] ths){
long s1 = System.currentTimeMillis();
Arrays.asList(ths).forEach(t->t.start());
Arrays.asList(ths).forEach(t->{
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
long s2 = System.currentTimeMillis();
System.out.println(s2 - s1);
}
}
/**
* DelayQueue等待时间长的先往外拿,可以用来做定时执行任务。
*/
public class DelayQueueTs {
static BlockingQueue<MyTask> tasks = new DelayQueue();
static Random r = new Random();
private static class MyTask implements Delayed {
long runningTime;
MyTask(long rt){
this.runningTime = rt;
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(runningTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
if(this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)){
return -1;
}else if(this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)){
return 1;
}else{
return 0;
}
}
@Override
public String toString() {
return "" + runningTime;
}
}
public static void main(String[] args) throws InterruptedException {
long now = System.currentTimeMillis();
MyTask t1 = new MyTask(now + 1000);
MyTask t2 = new MyTask(now + 2000);
MyTask t3 = new MyTask(now + 1500);
MyTask t4 = new MyTask(now + 2500);
MyTask t5 = new MyTask(now + 500);
tasks.put(t1);
tasks.put(t2);
tasks.put(t3);
tasks.put(t4);
tasks.put(t5);
System.out.println(tasks);
for (int i = 0; i < 5; i++){
System.out.println(tasks.take());
}
}
}
/**
* 加锁list和没加锁list
*/
public class SynChronizedList {
public static void main(String[] args) {
List<String> strs = new ArrayList<>();
List<String> strSync = Collections.synchronizedList(strs); //加锁list
}
}
public class TransferQueueTs {
public static void main(String[] args) throws InterruptedException {
LinkedTransferQueue<String> strs = new LinkedTransferQueue<>();
new Thread(()->{
try {
System.out.println(strs.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
//如果找不到消费者的情况下会阻塞
strs.transfer("aaa");
/*new Thread(()->{
try {
System.out.println(strs.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();*/
}
}
public class SynchronizedQueueTs {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> strs = new SynchronousQueue<>();
new Thread(()->{
try {
System.out.println(strs.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
strs.put("aaa"); //阻塞等待消费者消费
//strs.add("aaa");
System.out.println(strs.size());
}
}
/**
* 线程池
*/
public class ThreadPool {
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(5);//execute submit
for(int i = 0; i < 6; i++){
service.execute(()->{
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
});
}
System.out.println(service);
service.shutdown();
System.out.println(service.isTerminated());
System.out.println(service.isShutdown());
System.out.println(service);
TimeUnit.SECONDS.sleep(5);
System.out.println(service.isTerminated());
System.out.println(service.isShutdown());
System.out.println(service);
}
}
/**
* 缓存线程池,它的意思是要多少线程它创建多少,当然也有范围限制,
* int的最大值,当线程60秒没有执行,将关闭该线程。
*/
public class CachedPoolTs {
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newCachedThreadPool();
System.out.println(service);
for(int i = 0; i < 2; i++){
service.execute(()->{
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
});
}
System.out.println(service);
TimeUnit.SECONDS.sleep(66);
System.out.println(service);
}
}
public class ForkJoinPoolTs {
static int[] nums = new int[1000000];
static final int MAX_NUM = 50000;
static Random r = new Random();
static {
for(int i = 0; i < nums.length; i++){
nums[i] = r.nextInt(100);
}
System.out.println(Arrays.stream(nums).sum()); //stream api
}
/*static class AddTask extends RecursiveAction{
int start, end;
AddTask(int start, int end){
this.start = start;
this.end = end;
}
@Override
protected void compute() {
if(end - start <= MAX_NUM){
long sum = 0L;
for(int i = start; i < end; i++) sum += nums[i];
System.out.println("from:" + start + "to:" + end + " = " + sum);
}else{
int middle = start + (end - start)/2;
AddTask subTask1 = new AddTask(start, middle);
AddTask subTask2 = new AddTask(middle, start);
subTask1.fork();
subTask2.fork();
}
}
}*/
static class AddTask extends RecursiveTask<Long>{
int start, end;
AddTask(int start, int end){
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
if(end - start <= MAX_NUM){
long sum = 0L;
for(int i = start; i < end; i++) sum += nums[i];
return sum;
}
int middle = start + (end - start)/2;
AddTask subTask1 = new AddTask(start, middle);
AddTask subTask2 = new AddTask(middle, end);
subTask1.fork();
subTask2.fork();
return subTask1.join() + subTask2.join();
}
}
public static void main(String[] args) throws IOException {
ForkJoinPool forkJoinPool = new ForkJoinPool();
AddTask task = new AddTask(0, nums.length);
forkJoinPool.execute(task);
long result = task.join();
System.out.println(result);
//System.in.read();
}
}
public class FutureTs {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//new Callable() {Integer call();}
FutureTask<Integer> task = new FutureTask<>(()->{
TimeUnit.MILLISECONDS.sleep(500);
return 1000;
});
new Thread(task).start();
System.out.println(task.get());//阻塞
ExecutorService service = Executors.newFixedThreadPool(5);
Future<Integer> f = service.submit(()->{
TimeUnit.MILLISECONDS.sleep(500);
return 1;
});
//阻塞完以后f.get后,在f.isDone(),会返回true,否则false
//System.out.println(f.get());
System.out.println(f.isDone());
}
}
/**
* 线程池,并行计算
*/
public class ParallelComputing {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//这里进行普通的计算
long start = System.currentTimeMillis();
List<Integer> results = getPrime(1, 200000);
long end = System.currentTimeMillis();
System.out.println(end - start);
//这里类似于分四个线程,然后一起对结果进行计算
final int cpuCoreNum = 4;
ExecutorService service = Executors.newFixedThreadPool(cpuCoreNum);
MyTask t1 = new MyTask(1, 80000);
MyTask t2 = new MyTask(80001, 130000);
MyTask t3 = new MyTask(130001, 170000);
MyTask t4 = new MyTask(170001, 200000);
Future<List<Integer>> f1 = service.submit(t1);
Future<List<Integer>> f2 = service.submit(t2);
Future<List<Integer>> f3 = service.submit(t3);
Future<List<Integer>> f4 = service.submit(t4);
start = System.currentTimeMillis();
f1.get();
f2.get();
f3.get();
f4.get();
end = System.currentTimeMillis();
System.out.println(end - start);
}
static class MyTask implements Callable<List<Integer>>{
int startPos, endPos;
MyTask(int startPos, int endPos) {
this.startPos = startPos;
this.endPos = endPos;
}
@Override
public List<Integer> call() throws Exception {
List<Integer> r = getPrime(startPos, endPos);
return r;
}
}
static boolean isPrime(int num){
for(int i = 2; i <= num/2; i++){
if(num % i == 0)
return false;
}
return true;
}
static List<Integer> getPrime(int start, int end){
List<Integer> results = new ArrayList<>();
for(int i = start; i <= end; i++){
if(isPrime(i)) results.add(i);
}
return results;
}
}
/**
* 线程池执行定时任务
*/
public class ScheduledPoolTs {
public static void main(String[] args) {
ScheduledExecutorService service = Executors.newScheduledThreadPool(4);
service.scheduleAtFixedRate(()->{
try {
TimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}, 0, 500, TimeUnit.MILLISECONDS);
}
}
/**
* 单个线程池,它的作用就是不管你创建几个线程,其实他们都是同一个线程。
*/
public class SingleThreadPoolTs {
public static void main(String[] args) {
ExecutorService service = Executors.newSingleThreadExecutor();
for(int i = 0; i < 5; i++){
final int j = i;
service.execute(()->{
System.out.println(j + " " + Thread.currentThread().getName());
});
}
}
}
/**
* 这儿里的意思是线程会主动找任务去做
*/
public class WorkStealingPoolTs {
public static void main(String[] args) throws IOException {
ExecutorService service = Executors.newWorkStealingPool();
System.out.println(Runtime.getRuntime().availableProcessors());
service.execute(new R(1000));
service.execute(new R(2000));
service.execute(new R(2000));
service.execute(new R(2000));
service.execute(new R(2000));
//由于产生的是精力线程(守护线程、后台线程),主线程不阻塞的话,看不到输出
System.in.read();
}
static class R implements Runnable{
int time;
R(int t){
this.time = t;
}
@Override
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(time + " " + Thread.currentThread().getName());
}
}
}