1. 是车票窗口多线程的实现(还有一些同步工具CountDownLatch的使用)
package com.example.clawer.firstspringboot.newclawer.thread;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
/**
* @author geyul
* @title: Test
* @projectName firstspringboot0522
* @description: TODO
* @date 2019/5/29 17:51
*/
public class Ticket implements Runnable {
private Integer total;
private Integer count;
private String lock;
private CountDownLatch latch = null;
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public CountDownLatch getLatch() {
return latch;
}
public void setLatch(CountDownLatch latch) {
this.latch = latch;
}
public Ticket() {
this.total = 100;
this.count = 0;
this.lock="lock";
this.latch = new CountDownLatch(3);
}
@Override
public void run() {
while (true) {
synchronized (lock) {
if (total <= 0) {
System.out.println(Thread.currentThread().getName() + ":没票了,sorry");
latch.countDown();
return;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
total--;
count++;
System.out.println(Thread.currentThread().getName() + ":总共还有多少张票" + total + "。第" + count + "个人买。");
}
}
/*synchronized (this) {
while (total > 0) {
total--;
count++;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":总共还有多少张票" + total + "。第" + count + "个人买。");
}
}*/
}
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
// Vector<Thread> threads = new Vector<>();
Ticket ticket = new Ticket();
long l = System.currentTimeMillis();
Thread thread1 = new Thread(ticket, "1号");
Thread thread2 = new Thread(ticket, "2号");
Thread thread3 = new Thread(ticket, "3号");
thread1.start();
thread2.start();
thread3.start();
//thread1.join();
//thread2.join();
//thread3.join();
/* for (int i = 1;i < 6;i++){
Thread thread = new Thread(ticket, i+"号窗口");
threads.add(thread);
thread.start();
}
for (Thread thread : threads) {
thread.join();
}*/
ticket.latch.await();
System.out.println(System.currentTimeMillis()-l);
}
}
解释:synchronized代码块的位置大小真的很重要,他不是很灵活。因为在这里while相当循环买所有的票)在它外面加锁,相当与让一个线程卖所有票。
2 下面代码是另外的同步工具CyclicBarrier的使用(俗称人满发车)。
package com.example.clawer.firstspringboot.newclawer.thread;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* @author geyul
* @title: Test
* @projectName firstspringboot0522
* @description: TODO
* @date 2019/5/29 17:51
*/
public class Ticket implements Runnable {
private Integer total;
private Integer count;
private String lock;
private CyclicBarrier cyclicBarrier;
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public Integer getCount() {
return count;
}
public void setCyclicBarrier(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
public void setCount(Integer count) {
this.count = count;
}
public CyclicBarrier getCyclicBarrier() {
return cyclicBarrier;
}
public Ticket(CyclicBarrier cyclicBarrier) {
this.total = 100;
this.count = 0;
this.lock="lock";
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
while (true) {
synchronized (lock) {
if (total <= 0) {
System.out.println(Thread.currentThread().getName() + ":没票了,sorry");
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
total--;
count++;
System.out.println(Thread.currentThread().getName() + ":总共还有多少张票" + total + "。第" + count + "个人买。");
}
}
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
/*synchronized (this) {
while (total > 0) {
total--;
count++;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":总共还有多少张票" + total + "。第" + count + "个人买。");
}
}*/
}
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
// Vector<Thread> threads = new Vector<>();
CyclicBarrier cyclicBarrier = new CyclicBarrier(4);
Ticket ticket = new Ticket(cyclicBarrier);
long l = System.currentTimeMillis();
Thread thread1 = new Thread(ticket, "1号");
Thread thread2 = new Thread(ticket, "2号");
Thread thread3 = new Thread(ticket, "3号");
thread1.start();
thread2.start();
thread3.start();
//thread1.join();
//thread2.join();
//thread3.join();
/* for (int i = 1;i < 6;i++){
Thread thread = new Thread(ticket, i+"号窗口");
threads.add(thread);
thread.start();
}
for (Thread thread : threads) {
thread.join();
}*/
ticket.cyclicBarrier.await();
System.out.println(System.currentTimeMillis()-l);
}
}
解释:上面用来await()的线程数和设置的parties相同,在一起运行。还有一些方法没试,如reset();