织梦做淘宝客网站,网站开发的项目开发计划,收录快的网站,代理商平台多线程 并发
并行 多线程实现方式 1.继承Thread类
自己创建一个类extends thread类
Start方法开启线程#xff0c;自动执行重写之后的run方法 2.实现runable接口
自己创建一个类implements runnable Myrun不能直接使用getname方法#xff0c;因为这个方法是thread类的方法…多线程 并发
并行 多线程实现方式 1.继承Thread类
自己创建一个类extends thread类
Start方法开启线程自动执行重写之后的run方法 2.实现runable接口
自己创建一个类implements runnable Myrun不能直接使用getname方法因为这个方法是thread类的方法
所以需要得到当前线程的thread对象再用getname方法 3.用callable接口和future接口方法
抽象方法run没有返回值获取不了运行结果
实现callable接口
重写call方法
Future接口不能直接用要用他的实现类futuretask管理线程运行结果 Thread的方法 Getname
没有起名有默认名字Thread-0Thread-1.。。
Setname
设置线程名字可以用set也可以用构造方法但是构造方法不能继承要自己重新写个构造方法通过super继承父类的构造方法 CurrentThread Sleep 静态方法 用Thread.sleep调用 抢占式调度
随机
优先级最高10最小1默认5
Setpriorityint
Getpriority 守护线程
SetDaemontrue
非守护和守护默认没有优先级之分
非守护结束守护慢慢就也会结束 出让线程
Thread.yield()
让结果每一个线程尽可能均匀运行 插入线程 线程的生命周期
有执行资格有资格去抢CPU的执行权
没有执行权还没抢到执行权不能执行代码 线程安全 Ticket要用static修饰这样所有这个类的对象就可以共享ticket 为什么会出现这个问题 执行代码时线程随时都会被其他线程抢夺执行权 如何解决
同步代码块
让一个线程执行完完整的一次同步代码块里的代码才可以重新抢夺执行权 Synchronized(锁对象){}
锁对象是任意的但是一定是唯一的前面用static修饰 锁对象可以是本类的字节码文件 同步方法
如果想把一个方法里面所有的代码都锁起来就不需要同步代码块
直接将synchronized加在方法上 用runable的时候由于只需要创建一次所以里面的ticket就可以不用static修饰 Stringbuffer用于多线程环境里面的方法和stringbuilder一样的 Lock锁
是一个接口创建对象要用实现类reentrantlock 以上代码可能出现的问题
如果lock没有用static修饰
则会所有的线程都会创建一个lock重复ticket超出范围的问题又会出现所以要加static修饰即所有线程共享一个lock就能解决 2.程序不停止
没有执行lock.unlock()方法有线程一直停留在lock.lock()方法所以程序没有停止
如何避免
把unlock写到finally中保证unlock一定会执行 死锁
不要让两个锁嵌套起来写这样程序就运行不下去 生产者和消费者
等待唤醒机制
生产者生产数据
消费者消费数据 消费者等待 生产者等待 完整机制 方法
Wait
一般用notifyall
这几个方法要通过锁对象来进行调用 重写run方法的套路 Desk Foodie Cookie 测试类 第二种实现方式阻塞队列方式
数组有界链表无界 生产者和消费者要使用同一个阻塞队列
不需要在写锁对象因为put和take方法的底层就已经有锁了
Take有返回值类型和put进去的数据一样 线程的状态 Java没有定义运行状态只有剩下的六种状态
为什么没有
因为线程抢到CPU的执行权之后当前线程就会交给操作系统管理虚拟机就不会再管这个线程了 package exericise;public class exercise1 {public static void main(String[] args) {window t1 new window();window t2 new window();t1.setName(窗口1);t2.setName(窗口2);t1.start();t2.start();}
}package exericise;public class window extends Thread{static int ticket 1000;Overridepublic void run() {while (true) {synchronized (exercise1.class){if (ticket ! 0){ticket--;try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(getName() 还有ticket张票);}else {break;}}}}
} package exericise;public class exercise2 {public static void main(String[] args) {Person t1 new Person();Person t2 new Person();t1.setName(Person1);t2.setName(Person2);t1.start();t2.start();}
}package exericise;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Person extends Thread {static int gift 1000;static Lock lock new ReentrantLock();Overridepublic void run() {while (true) {lock.lock();try {if (!(gift 10)) {System.out.println(getName() 送出第 gift 个礼物);gift--;} else {break;}} catch (Exception e) {throw new RuntimeException(e);} finally {lock.unlock();}}}
} package exericise;public class exercise3 {public static void main(String[] args) {Number t1 new Number();Number t2 new Number();t1.setName(线程1);t2.setName(线程2);t1.start();t2.start();}
}package exericise;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Number extends Thread{static int start 1;static int end 100;static Lock lock new ReentrantLock();Overridepublic void run() {while (true) {lock.lock();try {if (start end) {//判断是不是奇数if (start %2 1) {//是就打印System.out.println(getName() : start);}start;}else {//超过范围break;}} catch (Exception e) {throw new RuntimeException(e);} finally {lock.unlock();}}}
} package exericise;import java.util.Arrays;
import java.util.Random;public class exercise4 {public static void main(String[] args) {//随机分成3个红包Random r new Random();for (int i 0; i redBao.arr.length; i) {if (i redBao.arr.length - 1) {redBao.arr[i] redBao.redPocket;}else {redBao.arr[i] r.nextDouble(0.01,redBao.redPocket);redBao.redPocket - redBao.arr[i];}}System.out.println(Arrays.toString(redBao.arr));redBao rb1 new redBao();redBao rb2 new redBao();redBao rb3 new redBao();redBao rb4 new redBao();redBao rb5 new redBao();rb1.setName(No.1);rb2.setName(No.2);rb3.setName(No.3);rb4.setName(No.4);rb5.setName(No.5);rb1.start();rb2.start();rb3.start();rb4.start();rb5.start();}
}
package exericise;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class redBao extends Thread{static double redPocket 100;//标记是否已经抢到过boolean flag false;static double[] arr new double[3];static Lock lock new ReentrantLock();static int index 0;static int end 1;Overridepublic void run() {lock.lock();try {if (!flag index 2){//还没抢到过红包System.out.println(getName() 抢到了 arr[index] 块钱);index;flag true;}if (end 3) {System.out.println(getName() 没抢到);}end;} catch (Exception e) {throw new RuntimeException(e);} finally {lock.unlock();}}
} 在run方法中定义一个集合则所有的进程都会在自己的栈中的run方法里创建出自己的集合这个集合在不同的进程中独立互不影响
注意其实每一个线程都会有自己独立的栈包括main里面创建的元素互不影响除非是static 线程池 创建线程浪费时间
用完直接丢弃浪费资源 原理 一般不会关闭线程池因为服务器24小时都会运行所以随时都会新任务进来所以一般不会关闭线程池 Submit提交任务
Shutdown销毁线程池
0 自定义线程池
什么时候创建临时线程
核心线程已被占用而且排队队伍已满这是才创建临时线程 先提交的任务不一定先执行
如图任务4 5 6在排队临时线程处理任务7 8 当提交的任务数量大于核心线程数临时线程数队伍长度剩下的任务10就会触发任务拒绝策略 自定义线程池设置七个参数 ThreadPoolExecutor 到底怎么设置才合适 最大并行数
系统处理器的线程数4核8线程8就是最大并行数 CPU密集型运算读取文件较少计算数据较多
为什么1如果前面的线程出问题则多出来的线程就可以顶上不浪费cpu的时钟周期不被浪费 IO密集性运算现在的项目大多都是IO密集性的读取服务器文件操作多
怎么得到计算时间
通过thread dump的工具来测试计算时间