上面的东西就是很多个进程。每个进程里面包括很多个线程。 线程里又有主线程和分支线程的区别。 就像启动一个java项目。 main函数是主线程,同时会开启一个gc线程垃圾回收。还会开启一些线程。
像是玩元神, 元神那边有服务器。 我们在玩这个游戏,那么元神的服务器程序会被我占用。 那么,如果别人也想玩元神,也需要占用服务器的程序。
如果是单线程的, 那么只能我玩几秒钟,别人等我操作结束了,才能进行操作他的角色。
如果是都线程就不一样了, 我和别人能够在同一个时刻操控各自的角色,一起愉快的玩原神了。
java.Thread
特别喜欢狂神,下面是普通的方法,就是必须要等待 run()方法结束了才能继续往下跑
这里开启了一个子线程,让子线程执行run()方法,主线程继续往下跑
线程船舰的三种方式继承Thread类,Runnable接口,Callable接口。
thread类继承了Runnable接口 都有一个run()方法
Callable接口 有一个call方法
程序需要使用多线程:
那么需要继承thread类,重写run方法 。 函数钟使用它,那么需要调用start方法。
举个列子,为什开启多线程,是同时独立执行的,会产生交替现象(但是线程开启不一定立即执行,是由cpu开启的)
实战:使用多线程下载多个图片
结果可以看到,线程是单独执行的,不是依次向下依次执行的。
实现Runnable接口类 。 将runnable实现的对象放入到thread对象中实现
总结一下继承Thread 和实现Runnable接口 那种方法比较好。一般都是比较建议Runnable的。因为Runnable接口不会是实现的。而Thread是继承的。oop只能够继承一个对象。所以说如果继承了Thread类就不能够继承其他的类了,建议使用Runnabel进行是实现。
那么抢票: 可能会出现问题,数据紊乱
手撕生产者消费者模型
synchronize实现生产者消费者模型
package org.example.consumer_and_pro;
public class Message {
private int id;
private Object message;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Object getMessage() {
return message;
}
public Message(int id, Object message) {
this.id = id;
this.message = message;
}
public void setMessage(Object message) {
this.message = message;
}
@Override
public String toString() {
return "Message{" +
"id=" + id +
", message=" + message +
'}';
}
}
package org.example.consumer_and_pro;
import java.util.LinkedList;
public class MessageQueue {
private LinkedList<Message> list = new LinkedList<Message>();
//初始化容器
private int capacity;
public MessageQueue(int capacity){
this.capacity = capacity;
}
//存入消息
public void put(Message message){
synchronized (list){
while (list.size() == capacity){
try{
System.err.println("队列已满,<生产者>请稍后....");
list.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//尾部添加消息
list.add(message);
System.out.println("生产消息!"+message);
//唤醒等待的消费者
list.notifyAll();
}
}
//获取消息
public Message take(){
synchronized (list){
while (list.isEmpty()){
try {
System.err.println("队列已空,<消费者>请稍后....");
list.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//从对头取出消息并且返回
Message message = list.removeFirst();
System.out.println("消费了消息"+message);
//通知生产者生产
list.notifyAll();
return message;
}
}
}
package org.example.consumer_and_pro;
import java.util.concurrent.TimeUnit;
public class ConAndPro {
public static void main(String[] args) {
MessageQueue msque = new MessageQueue(3);
//生产者
for (int i = 0; i < 8; i++) {
//Lambda中引用外部局部变量必须为final
int id = i;
new Thread(()->{
msque.put(new Message(id,"值"+id));
},"生产者"+i).start();
}
new Thread(()->{
while (true){
try {
TimeUnit.SECONDS.sleep(1);
msque.take();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
},"消费者").start();
}
}