闸北做网站公司,图书网站开发背景,内部局域网怎么搭建,网站上官网标识怎么做一、死锁
1.概述
死锁 : 死锁是指两个或两个以上的进程在执行过程中#xff0c;由于竞争资源或者由于彼此通信而造成的一种阻塞的现象#xff0c;若无外力作用#xff0c;它们都将无法往下执行。此时称系统处于死锁状态或系统产生了死锁#xff0c;这些永远在互相等待的进…一、死锁
1.概述
死锁 : 死锁是指两个或两个以上的进程在执行过程中由于竞争资源或者由于彼此通信而造成的一种阻塞的现象若无外力作用它们都将无法往下执行。此时称系统处于死锁状态或系统产生了死锁这些永远在互相等待的进程称为死锁进程原理 : 某个线程执行完成,需要先后嵌套锁定两个对象,在这个过程中,先锁定了第一个对象另一个线程执行完成也需要先后嵌套锁定两个对象,在这个过程中,先锁定了第二个对象第一个线程执行中,要执行到第二个对象的时候,发现第二个对象被锁定,进入等待状态,等待交出锁第二个线程执行中,要执行到第一个对象的时候,发现第一个对象也被锁定,也进入等待状态此时两个线程都在等待对方交出锁,导致死锁
2.代码实现
public class Thread_01_DeadLock {public static void main(String[] args) {Object o1new Object();Object o2new Object();Thread t1new Thread(new T1(o1, o2));Thread t2new Thread(new T2(o1, o2));t1.start();t2.start();}
}
class T1 implements Runnable{Object o1;Object o2;public T1(Object o1,Object o2){this.o1o1;this.o2o2;}Overridepublic void run() {synchronized (o1) {
// try {//加上睡眠一定死锁
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }System.out.println(Thread.currentThread().getName()--T1o1已锁定);synchronized (o2) {System.out.println(Thread.currentThread().getName()--T1o2已锁定);}}System.out.println(t1执行完成);}
}
class T2 implements Runnable{Object o1;Object o2;public T2(Object o1,Object o2){this.o1o1;this.o2o2;}Overridepublic void run() {try {//加上睡眠一定不死锁Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (o2) {System.out.println(Thread.currentThread().getName()--T2o2已锁定);synchronized (o1) {System.out.println(Thread.currentThread().getName()--T2o1已锁定);}}System.out.println(t2执行完成);}
}二、线程通信
1.概述
Object中的方法wait : 让当前线程进入等待状态(挂起),并释放锁,当被唤醒之后,接着挂起的位置继续执行,假如之前执行了1、2到3挂起那么被唤醒后接着执行3notify : 唤醒一个在该对象中挂起的任意一个线程notifyAll : 唤醒在该对象中挂起的所有线程这几个方法必须出现在加锁的成员方法中wait : 如果是无参,则不会自动醒,也可以传入long类型的值,代表毫秒数,多久之后自动醒wait 和 sleep的区别 : sleep : 让当前线程进入睡眠状态, 是静态方法,和是否加锁没有关系,如果在加锁的方法中,也不会释放锁wait : 让当前线程进入挂起等待状态,必须在加锁的成员方法中,另外会释放锁
2.使用方式
public class Thread_03_Wait {public static void main(String[] args) throws InterruptedException {Num numnew Num();Thread t1new PrintNum(num);Thread t2new PrintNum(num);t1.start();Thread.sleep(10);//保证t1先执行t2.start();}
}
class PrintNum extends Thread{Num num;public PrintNum(Num num){this.numnum;}Overridepublic void run() {while (true) {num.printNums();}}
}
class Num{private int count 1;public synchronized void printNums(){System.out.println(Thread.currentThread().getName()--count);count;// 唤醒等待的进程this.notifyAll();try {Thread.sleep(1000);// 进入挂起状态并释放锁this.wait();} catch (InterruptedException e) {e.printStackTrace();}}
}3.生产者消费者 3.1.示例
public class Thread_04_Producer {public static void main(String[] args) {SynStack ssnew SynStack();Thread producer1new Thread(new Producer(ss));Thread producer2new Thread(new Producer(ss));Thread consumer1new Thread(new Consumer(ss));Thread consumer2new Thread(new Consumer(ss));producer1.start();producer2.start();consumer1.start();consumer2.start();}
}
class Producer implements Runnable{private SynStack ss;public Producer(SynStack ss){this.ssss;}Overridepublic void run() {for (int i 0; i 26; i) {ss.push((char)(ai));}}
}
class Consumer implements Runnable{private SynStack ss;public Consumer(SynStack ss){this.ssss;}Overridepublic void run() {for (int i 0; i 26; i) {ss.pop();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}
}
//业务类
class SynStack{int count0;// 货物数量char[] datanew char[6];// 记录货物数量// 生产货物public synchronized void push(char ch){// 判断货物满没满while(count data.length){//try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}//仓库空了该生产了此时应该唤醒挂起的消费者if (count0) {this.notifyAll();}data[count]ch;System.out.println(Thread.currentThread().getName()生产了 ch 还剩 count 个货物);}// 消费货物public synchronized char pop(){// 判断货物空没空while(count 0){try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}//仓库满了该挂起了此时应该唤醒挂起的生产者if (countdata.length) {this.notifyAll();}char chdata[--count];System.out.println(Thread.currentThread().getName()消费了 ch 还剩 count 个货物);return ch;}
}三、单例模式
public class SingLeton {private SingLeton(){}// volatile 防止指令重排private volatile static SingLeton singLeton;public static SingLeton getInstance(){// 多线程可能同时进入if (singLetonnull) {// 一个线程进入synchronized (SingLeton.class) {if (singLetonnull) {// 一个线程进入后 对象就不再是null其他的线程将无法进入singLetonnew SingLeton();} }}return singLeton;}
}四、线程池
线程池的作用 线程池作用就是限制系统中执行线程的数量。 根据系统的环境情况可以自动或手动设置线程数量达到运行的最佳效果少了浪费了系统资源多了造成系统拥挤效率不高。用线程池控制线程数量其他线程排队等候。一个任务执行完毕再从队列的中取最前面的任务开始执行。若队列中没有等待进程线程池的这一资源处于等待。当一个新任务需要运行时如果线程池中有等待的工作线程就可以开始运行了否则进入等待队列。为什么要用线程池: 减少了创建和销毁线程的次数每个工作线程都可以被重复利用可执行多个任务。可以根据系统的承受能力调整线程池中工作线线程的数目防止因为消耗过多的内存而把服务器累趴下(每个线程需要大约1MB内存线程开的越多消耗的内存也就越大最后死机)