总结:
在线程中进行并发和并行
有返回值,可以获得多线程的结果
特点:
演示方法:
返回线程的名字:
public class Mythread_01 extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName() + "@" + i);
}
}
}
返回的默认名字格式为Thread-序号
抢占式调度特点:随机
//使用setPriority来设置优先级
t1.setPriority(1);
t2.setPriority(10);
t2.start();
t1.start();
当其他非守护线程执行完毕,守护线程会陆续结束
当主线程结束,守护线程是跟着结束
线程.join()
可以讲线程提前用完
标准写法:
Lock lock = new ReentrantLock();
while(true){
// synchronized (Myrunnable.class){
lock.lock();
try {
if(ticket == 100){
break;
}else{
Thread.sleep(10);
ticket++;
System.out.println(Thread.currentThread().getName() + " sell " + ticket + " tickets");
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
死锁是一种错误,需要我们去避免的
特点:
完整过程:
代码执行的流程:
分为三块代码:
Desk:控制消费者和生产者的行为
package 生产者消费者;
public class Desk {
//Desk:控制生产者和消费者的行为
// 是否有面条
public static int foodFlag = 0;
//制造的个数
public static int count = 10;
//锁对象
public static Object lock = new Object();
}
Cook:生产者
package 生产者消费者;
public class Cook extends Thread {
@Override
public void run() {
while (true) {
synchronized (Desk.lock) {
if (Desk.count == 0) { //桌子上的食物做够了
break;
}else{
//判断是否有食物
if(Desk.foodFlag == 1){ //如果有食物 等待消费者来吃
try {
Desk.lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}else{
//如果没有食物 做
//修改食物状态
System.out.println("厨师做了一碗面条");
Desk.foodFlag = 1;
//叫醒消费者吃
Desk.lock.notifyAll();
}
}
}
}
}
}
Foodie:消费者
package 生产者消费者;
public class Foodie extends Thread{
@Override
public void run() {
while(true){
synchronized (Desk.lock){
if(Desk.count == 0){ //桌子上的食物做够了
break;
}else {
//判断桌子上有没有面条
if(Desk.foodFlag == 0){
//如果没有 就等待
try {
Desk.lock.wait(); //让线程等待
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}else{ //如果有 直接开吃
Desk.count--;
System.out.println("吃货吃了一碗,还剩" + Desk.count + "碗!");
//唤醒厨师! 份数-1
Desk.lock.notifyAll();
//修改桌子的状态
Desk.foodFlag = 0;
}
}
}
}
}
}
实现类:
ArrayBlockingQueue
LinkedBlockingQueue
队列和链表自带锁
七大状态:
当在run方法中创建了一个集合,那么每一个线程都会维持一个创建的集合(类似于static)
代码:
计算类型多:
读取文件或者数据库比较多: