1、进程和线程
①是什么?
答:
1、进程:是并发执行的程序在执行过程中进行系统资源分配和调度的基本单位。
2、线程:线程是进程的执行单元,比进程更小的独立运行的基本单位。也被成为轻量级进程。
②、进程和线程的区别?
答:
进程是享有独立的地址空间,而同一进程的线程共享本进程的地址空间。一个进程崩溃不会影响其它的进程;而一个进程中的某个线程崩溃会导致进程崩溃,从而使本进程的其它线程崩溃。多进程中的资源是不能共享的,而一个进程中的多个线程资源共享。
2、线程的生命周期
①新生态(new):一个线程对象实例化完成,还没有做任何操作
②就绪态(ready):一个线程已经被开启,已经开始争抢CPU时间片
③运行态(run):一个线程抢到了CPU时间片,开始执行线程中的逻辑。
④阻塞态(Interrupt):一个线程执行过程中,受到某些操作的影响,放弃了已经获取的CPU时间片,并且不再参与时间片的争抢,此时线程处于挂起状态。
⑤死亡态(Dead):一个线程需要被销毁。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b2dfdfe90a827eaa8acb3837b80961bd.png#pic_center)
3、创建线程的两种方式(继承Thread类,实现Runnable接口)
package cn.cduestc.thread;
public class ThreadTest {
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start();
Runnable r1 = ()->{
for (int i = 0;i <1000;i++){
System.out.println("实现runnable类方式实现多线程:"+i);
}
};
Thread t2 = new Thread(r1);
t2.start();
}
}
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0;i <1000;i++){
System.out.println("继承Thread类方式实现多线程:"+i);
}
}
}
4、线程的命名、睡眠、优先级
package cn.cduestc.thread;
public class ThreadTest2 {
public static void main(String[] args) {
test2();
}
public static void test2(){
Runnable r = new Runnable(){
@Override
public void run() {
for (int i = 0;i < 10;i++){
if(i == 3){
Thread.yield();
}
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
};
Thread t1 = new Thread(r,"线程一");
Thread t2 = new Thread(r,"线程二");
t1.start();
t2.start();
}
public static void test1(){
MyThread2 t1 = new MyThread2("线程一");
MyThread2 t2 = new MyThread2("线程二");
t1.setPriority(1);
t2.setPriority(10);
t1.start();
t2.start();
}
}
class MyThread2 extends Thread{
public MyThread2(){}
public MyThread2(String name){
this.setName(name);
}
@Override
public void run() {
for (int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
5、同步代码段的方式解决这一问题
package cn.cduestc.thread;
public class SynchronizedDemo {
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
while (ticket.num > 0){
synchronized (""){
if(ticket.num <= 0){
return;
}
System.out.println(Thread.currentThread().getName()+"卖出一张票,剩余"+ --ticket.num +"张");
}
}
}
};
Thread t1 = new Thread(r,"甲");
Thread t2 = new Thread(r,"乙");
Thread t3 = new Thread(r,"丙");
Thread t4 = new Thread(r,"丁");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class ticket {
public static int num = 100;
}
6、同步方法解决问题
package cn.cduestc.thread;
public class SynchronizedDemo2 {
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
while (ticket2.num > 0){
ticket2.sell();
}
}
};
Thread t1 = new Thread(r,"甲");
Thread t2 = new Thread(r,"乙");
Thread t3 = new Thread(r,"丙");
Thread t4 = new Thread(r,"丁");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class ticket2 {
public static int num = 100;
public synchronized static void sell(){
if (num <= 0){
return;
}
--num;
System.out.println(Thread.currentThread().getName()+"卖出一张票,剩余"+num+"张");
}
}
7、使用ReentrantLock锁解决问题
package cn.cduestc.thread;
import java.util.concurrent.locks.ReentrantLock;
public class LockDemo {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Runnable r = new Runnable() {
@Override
public void run() {
while (ticket2.num > 0){
lock.lock();
if(ticket2.num <= 0){
lock.unlock();
return;
}
System.out.println(Thread.currentThread().getName()+"卖出一张票,剩余"+ --ticket2.num +"张");
lock.unlock();
}
}
};
Thread t1 = new Thread(r,"甲");
Thread t2 = new Thread(r,"乙");
Thread t3 = new Thread(r,"丙");
Thread t4 = new Thread(r,"丁");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
8、死锁
package cn.cduestc.thread;
public class DieLock {
public static void main(String[] args) {
Runnable r1 = () -> {
synchronized ("A") {
System.out.println("甲持有了A锁,等待B锁");
synchronized ("B") {
System.out.println("甲持有了A锁和B锁");
}
}
};
Runnable r2 = () -> {
synchronized ("B") {
System.out.println("乙持有了B锁,等待A锁");
synchronized ("A") {
System.out.println("乙持有了A锁和B锁");
}
}
};
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}
9、解决死锁问题(使用wait,notify,notifyAll)
package cn.cduestc.thread;
public class DieLock2 {
public static void main(String[] args) {
Runnable r1 = () -> {
synchronized ("A") {
System.out.println("甲持有了A锁,等待B锁");
try {
"A".wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized ("B") {
System.out.println("甲持有了A锁和B锁");
}
}
};
Runnable r2 = () -> {
synchronized ("B") {
System.out.println("乙持有了B锁,等待A锁");
synchronized ("A") {
System.out.println("乙持有了A锁和B锁");
"A".notifyAll();
}
}
};
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}
10、生产者消费者模式
①产品(Product)
package cn.cduestc.productorAndConsumer;
public class Product {
private String name;
public Product(String name){
this.name = name;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
}
②产品池(ProductPool)
package cn.cduestc.productorAndConsumer;
import java.util.ArrayList;
import java.util.List;
public class ProductPool {
private List<Product> productList;
private int maxSize = 0;
public ProductPool (int maxSize){
this.productList = new ArrayList<Product>(15);
this.maxSize = maxSize;
}
public synchronized void push(Product product){
if(this.productList.size() == maxSize){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.productList.add(product);
this.notifyAll();
}
public synchronized Product pop(){
if(this.productList.size() == 0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Product product = this.productList.remove(0);
this.notifyAll();
return product;
}
}
③生产者(Productor):这里使用的是死循环
package cn.cduestc.productorAndConsumer;
public class Productor extends Thread {
private ProductPool productPool;
public Productor(ProductPool productPool){
this.productPool = productPool;
}
@Override
public void run() {
while(true){
String name = (int)(Math.random()*100)+"号产品";
Product product = new Product(name);
this.productPool.push(product);
System.out.println("生产者了一个产品:"+name);
}
}
}
④消费者(Consumer):这里也是使用死循环
package cn.cduestc.productorAndConsumer;
public class Consumer extends Thread {
private ProductPool productPool;
public Consumer(ProductPool productPool){
this.productPool = productPool;
}
@Override
public void run() {
while (true){
Product product = this.productPool.pop();
System.out.println("消费者消费了一个产品:"+product.getName());
}
}
}
⑤测试代码
package cn.cduestc.productorAndConsumer;
public class Program {
public static void main(String[] args) {
ProductPool productPool = new ProductPool(15);
new Productor(productPool).start();
new Consumer(productPool).start();
}
}