多线程实现方式(三种显示方式)
①继承thread类
public class Test {
static class MyThread extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程执行了");
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.setName("自定义");
myThread.start();
}
}
②实现Runnable接口
public class Test02 {
static class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程执行了");
}
}
public static void main(String[] args) {
MyRunnable myRunnable=new MyRunnable();
Thread thread=new Thread(myRunnable);
thread.start();
}
}
③实现Callable接口
public class Test03 {
static class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName() + "线程执行了");
return "null";
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable myCallable = new MyCallable();
FutureTask<String> futureTask=new FutureTask<String>(myCallable);
FutureTask<String> futureTask2=new FutureTask<String>(myCallable);
Thread t1 = new Thread(futureTask);
Thread t2 = new Thread(futureTask2);
t1.start();
t2.start();
// System.out.println(futureTask.get());
}
多线程处理共享变量存在数据安全问题
模拟两个窗口共同售卖100张票
public class Test04 {
static class MyRunnable implements Runnable {
private Integer ticketCount = 10;
public MyRunnable(Integer ticketCount) {
this.ticketCount = ticketCount;
}
public MyRunnable() {
}
@Override
public void run() {
while (true) {
if (ticketCount <= 0) {
break;
} else {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
ticketCount--;
System.out.println(Thread.currentThread().getName() + "正在售票,还剩" + ticketCount + "张票");
}
}
}
}
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable(10);
Thread t1 = new Thread(myRunnable);
t1.setName("窗口一");
Thread t2 = new Thread(myRunnable);
t2.setName("窗口二");
t1.start();
t2.start();
}
}
运行结果如下图:
尝试加锁解决
public class Test04 {
static class MyRunnable implements Runnable {
private static Integer ticketCount = 10;
private final static ReentrantLock reentrantLock = new ReentrantLock();
public MyRunnable() {
}
@Override
public void run() {
while (true) {
try {
reentrantLock.lock();
if (ticketCount <= 0) {
break;
} else {
Thread.sleep(50);
ticketCount--;
System.out.println(Thread.currentThread().getName() + "正在售票,还剩" + ticketCount + "张票");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
}
}
}
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread t1 = new Thread(myRunnable);
t1.setName("窗口一");
Thread t2 = new Thread(myRunnable);
t2.setName("窗口二");
t1.start();
t2.start();
}
}
生产者和消费者的等待唤醒模型
/**
* 仓库类,存放产品的容器类
*/
@Data
public class Store {
private Integer target;
private Integer count = 0;
private final Object lock = new Object();
private Boolean have=Boolean.FALSE;
public Store() {
this(10);
}
public Store(Integer target) {
this.target = target;
}
}
/**
* 生产者
*/
public class Producer implements Runnable {
private final Store store;
public Producer(Store store) {
this.store = store;
}
@Override
public void run() {
while (true) {
synchronized (store.getLock()) {
if (store.getCount() >= store.getTarget()) {
break;
} else {
if (store.getHave()) {
try {
store.getLock().wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
store.setCount(store.getCount()+1);
System.out.println(Thread.currentThread().getName()+"生产第"+store.getCount()+"个");
store.setHave(Boolean.TRUE);
store.getLock().notifyAll();
}
}
}
}
}
}
/**
* 消费者
*/
public class Consumer implements Runnable {
private final Store store;
public Consumer(Store store) {
this.store = store;
}
@Override
public void run() {
while (true) {
synchronized (store.getLock()) {
if (store.getHave()) {
System.out.println(Thread.currentThread().getName()+"消费第"+store.getCount()+"个");
store.setHave(Boolean.FALSE);
if (store.getCount() >= store.getTarget()) {
break;
}
store.getLock().notifyAll();
} else {
try {
store.getLock().wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
public class Test05 {
public static void main(String[] args) {
Store store = new Store(10);
Producer producer = new Producer(store);
Consumer consumer = new Consumer(store);
Thread t1 = new Thread(producer);
Thread t2 = new Thread(consumer);
t1.setName("生产者");
t2.setName("消费者");
t1.start();
t2.start();
}
}
阻塞队列实现等待唤醒
@Data
public class Store {
private final Integer target;
private Integer count = 0;
}
public class Producer extends Thread {
private final ArrayBlockingQueue<String> arrayBlockingQueue;
private final Store store;
public Producer(ArrayBlockingQueue<String> arrayBlockingQueue, Store store) {
this.arrayBlockingQueue = arrayBlockingQueue;
this.store = store;
}
@Override
public void run() {
while (true) {
try {
if (store.getCount() >= store.getTarget()) {
break;
} else {
if (arrayBlockingQueue.isEmpty()) {
arrayBlockingQueue.put("产品");
store.setCount(store.getCount() + 1);
System.out.println("生产了一个产品"+store.getCount());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public class Consumer extends Thread {
private final ArrayBlockingQueue<String> arrayBlockingQueue;
private final Store store;
public Consumer(ArrayBlockingQueue<String> arrayBlockingQueue, Store store) {
this.arrayBlockingQueue = arrayBlockingQueue;
this.store = store;
}
@Override
public void run() {
while (true) {
try {
if (!arrayBlockingQueue.isEmpty()) {
String take = arrayBlockingQueue.take();
System.out.println("消费了一个" + take + store.getCount());
if (store.getCount() >= store.getTarget()) break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public class Test01 {
public static void main(String[] args) {
ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(1);
Store store = new Store(10);
Consumer consumer = new Consumer(arrayBlockingQueue,store);
Producer producer = new Producer(arrayBlockingQueue,store);
consumer.start();
producer.start();
}
}