java是什么意思,java和python哪个好
10-1 多线程从软件或硬件上实现多个线程并发执行的技术能够在同一时间同时执行多个线程,提升性能并发和并行
并行-在同一时刻多个中央处理器上同时运行并发-多个线程在同一个中央处理器上交替运行进程和线程
进程-下在运行的软件
1.独立的-一个能独立运行的基本单位,同时也是操作系统分资源和调度的独立单位。
2.动态性-是程序的一次执行过程,是动态产生的,动态消亡的
3.并发性-可以和其它进行并发运行线程-进程中单个顺序控制流,是一条执行路径
1.单线程-在进程中只有一条执行路径
2.多进程-在进程中有多条执行路径多线程的实现方式继承线程公共静态void main(String[] args) {
my head 1 my head 1=new my head 1();
my head 1 my head 2=new my head 1();
我的脑袋1。start();
我的脑袋2。start();
}
公共类MyThead1扩展线程{
@覆盖
公共无效运行(){
for(int I=0;i 100i ) {
系统。出去。println(一);
}
}
}两个小问题
为什么要重写跑?-线程要执行的代码奔跑和开始有什么区别?-调用开始才能启动线程,运行只是对象的方法没有创建线程实现可追捕的接口公共静态void main(String[] args) {
Thread Thread=new Thread(new my ruable());
Thread Thread 1=新线程(new my ruable());
线程。start();
线程1。start();
}
公共类我的无法实现可运行{
@覆盖
公共无效运行(){
for(int I=0;i 100i ) {
系统。出去。println(一);
}
}
}实现请求即付的接口(未来)公共静态void main(String[] args)引发ExecutionException,InterruptedException {
未来任务字符串ft=新的未来任务(new my callable());
新螺纹(英尺)。start();
系统。出去。打印时间(英尺。get());//获取会死等.
}
公共类MyCallable实现可调用字符串{
@覆盖
公共字符串调用()引发异常{
for(int I=0;i 100i ) {
系统。出去。println(一);
}
回你好;
}
}三种实现方式的对比可运行可调用-扩展性强,不能在方法中调用线的方法卡尔巴莱-可以获得线程的返回值继承线程-编程简单,不能再继续扩展线方法设置获取名字getName/setName
如果没有设置,默认是:线程-编号,编号是线的静态成员,每创建一个编号一
获得线程对象
公共静态线程Thread.currentThread()
睡眠
公共静态线程.睡眠(毫秒);
线程的优先级
线程th=新线程(.)
th.setPriority(8) //1 - 10,数越高优先级越高守护线程
线程th=新线程(.)
th.setDeamon(true) //当所有前台线程结束,守护线程也会强制结束线程安全问题卖票案例实现公共类神话线索{
静态int ticketCount=100
公共静态void main(String[] args)引发ExecutionException、InterruptedException {
Runnable Runnable=new Runnable(){
@覆盖
公共无效运行(){
while (ticketCount 0) {
票数-;
System.out.println(
Thread.currentThread()。getName():票计数);
}
}
};
for(int I=0;i3;i ) {
螺纹螺纹=新线程(runnable);
thread.setName(窗口(I 1));
线程。start();
}
}
}貌似没什么问题,现实中,买票需要时间,我们加点延迟.
公共类神话线索{
静态int ticketCount=100
公共静态void main(String[] args)引发ExecutionException、InterruptedException {
Runnable Runnable=new Runnable(){
@覆盖
公共无效运行(){
while (ticketCount 0) {
尝试{
线程。睡眠(100);
} catch (InterruptedException e) {
}
票数-;
系统。出去。println(线程。当前线程().getName():票计数);
}
}
};
for(int I=0;i3;i ) {
螺纹螺纹=新线程(runnable);
thread.setName(窗口(I 1));
线程。start();
}
}
}
不同的窗口卖出了同一张票!
原因分析
多个线程对同一个资源操作没有做同机制.
解决安全问题
同步代码块
公共类神话线索{
静态int ticketCount=100
静态对象lock=new String();
公共静态void main(String[] args)引发ExecutionException、InterruptedException {
Runnable Runnable=new Runnable(){
@覆盖
公共无效运行(){
while (true) {
//锁对象必须唯一
同步(锁定){
if (ticketCount=0) {
打破;
}
票数-;
尝试{
线程.睡眠(十);
} catch (InterruptedException e) {
}
系统。出去。println(线程。当前线程().getName():票计数);
}
}
}
};
for(int I=0;i3;i ) {
螺纹螺纹=新线程(runnable);
thread.setName(窗口(I 1));
线程。start();
}
}
}同步方法
它的锁对象是这个,静态方法的锁对象:类名。班级
私有同步布尔同步方法()
{
.
返回真实的
}锁定
JDK5提供了锁对象
lock()unlock()reentrant lock lock=new reentrant lock();
尝试{
锁定。lock();
}
最后{
锁定。unlock();
}死锁
两个或者多个线程互相持有对方所需的的资源,导致这些线程一直处于等待状态。
公共类神话线索{
静态可重入锁lockA=new reentrant lock();
静态可重入锁lock b=new reentrant lock();
公共静态void main(String[] args)引发ExecutionException、InterruptedException {
新线程(()- {
while (true) {
洛卡。lock();//遇到A锁
lockb。lock();//遇到B锁
System.out.println(小A同学在走路);
lockb。unlock();
洛卡。unlock();
}
}).start();
新线程(()- {
while (true) {
lockb。lock();//遇到B锁
洛卡。lock();//遇到A锁
System.out.println(小B同学在走路);
洛卡。unlock();
lockb。unlock();
}
}).start();
}
}程序直接卡列.
生产者和消费者一个非常经典的多线程协作模式,弄懂它可以加深多线程编程的理解
队列满时,生产者(厨师)等待消费者消费产品,通知生产者(队列有空位,可以生产了)队列空时,消费者等待生产者把生产的产品放入队列,通知消费者(队列不空了,来拿吧)
代码实现目标类中的等待唤醒方法
waitnotifynotifyAll因为这里所有线程都是操作队列,所以由队列对象调用这些方法最合适.
公共类神话线索{
静态最终链表整数队列=新链表();
私有静态随机随机;
公共静态void main(String[] args)
引发ExecutionException,InterruptedException {
Random=new Random();
//生产者线程
新线程(()- {
while (true){
尝试{
线程。睡眠(500);
} catch (InterruptedException e) {
系统。出去。println();
}
同步(队列){
if(queue.size()=10) //满了等待
{
尝试{
排队。wait();
} catch (InterruptedException e) {
抛出新的运行时异常(e);
}
}
排队。补充(随机。nextint(200));
排队。notify all();
}
}
}).start();
//消费者线程
新线程(()- {
while (true) {
同步(队列)
{
if (queue.size()==0) {
尝试{
排队。wait();
} catch (InterruptedException e) {
抛出新的运行时异常(e);
}
}
系统。出去。println(队列。pop());
排队。notify all();
}
}
}).start();
}
}常用队列
数组dequee字符串d queue=新数组dequee(10);合框架整数queue=new链表();阻塞队列
ArrayBlockingQueue:有界LinkedBlockingQueue:无界公共类神话线索{
private static final ArrayBlockingQueue String queue=new ArrayBlockingQueue(10);
公共静态void main(String[] args) {
//生产
新线程(()- {
while (true) {
尝试{
queue.put(汉堡包);
} catch (InterruptedException e) {
抛出新的运行时异常(e);
}
}
}).start();
//消费
新线程(()- {
while (true) {
尝试{
系统。出去。println(队列。take());
} catch (InterruptedException e) {
抛出新的运行时异常(e);
}
}
}).start();
}
}拿,放在代码内部有锁定等待通知等操作,所以上层直接使用就行线程池不稳定的线程状态
六种状态(线程.状态()
newrunnableblockeddwaitingtime _ waiting已终止线程池基本原理每次需要线程时都创建,用完后销毁,资源浪费。
实施者默认线程池执行者服务=执行者。newcachedthreadpool();
executorService.submit(()- {
系统。出去。println(线程。当前线程().getName()
在执行了);
});
executorService.submit(()- {
系统。出去。println(线程。当前线程().getName()
在执行了);
});
执行服务。关闭();实施者创建指定上限的线程池公共类神话线索{
公共静态void main(String[] args) {
执行者服务=执行者。newfixedthreadpool(10);//池的容量
executorService.submit(()- {
系统。出去。println(线程。当前线程().getName()在执行了);
});
executorService.submit(()- {
系统。出去。println(线程。当前线程().getName()在执行了);
});
执行服务。关闭();
}
}ThreadPoolExecutor参数详解类比开饭馆
正式员工的数量- 》 核心线程餐厅最大员工数量- 》 最大线程临时工多长空间多长时间被辞退(值) - 》空闲时间临时工多长空间多长时间被辞退(单位) - .排队的客户-队列长度从哪里招人- 》创建线程的方式当排队人数过多,超出的顾客下次再来(拒绝服务) - 》拒绝策略公共类神话线索{
公共静态void main(String[] args) {
ThreadPoolExecutor pool=new ThreadPoolExecutor(
3, //核心线程数量
5, //最大线程数
2,
时间单位。秒,//空闲存活时间2s
新的ArrayBlockingQueue (10),
Executors.defaultThreadFactory(),
新建ThreadPoolExecutor .堕胎政策
);
pool.submit(()- {
系统。出去。println( running );
});
游泳池。关闭();
}
}任务拒绝策略ThreadPoolExecutor .堕胎政策丢弃并抛出异常(默认)ThreadPoolExecutor .废弃政策丢弃不抛出异常ThreadPoolExecutor .废弃政策把等待最久的任务丢掉,然后把当前任务加入队列ThreadPoolExecutor .呼叫者违反政策不使用线程池,直接新的,用完后销毁不稳定的问题公共类神话线索{
静态(同Internationalorganizations)国际组织内存=10000;
公共静态void main(String[] args) {
新线程(()- {
尝试{
线程。睡眠(100);
} catch (InterruptedException e) {
抛出新的运行时异常(e);
}
内存=300;
System.out.println(修改了钱数);
}).start();
新线程(()- {
while (memory==10000) {
}
System.out.println(钱不见了);
}).start();
}
}
线程2一直在正在…中.
堆内存是唯一的(内存是类的成员变量,类对象存储在堆中),每个线程都有自己的线程栈每一个线在使用堆变量时,先拷贝到一个副本中在线程中,每一次使用是从变量的副本中获取如果一个线程修改一共享数据的值,其它线程不一定能及时使用最新值
不稳定的解决公共类神话线索{
静态易失(同Internationalorganizations)国际组织内存=10000;
公共静态void main(String[] args) {
新线程(()- {
尝试{
线程。睡眠(100);
} catch (InterruptedException e) {
抛出新的运行时异常(e);
}
内存=300;
System.out.println(修改了钱数);
}).start();
新线程(()- {
while (memory==10000) {
}
System.out.println(钱不见了);
}).start();
}
}同步解决公共类神话线索{
静态(同Internationalorganizations)国际组织内存=10000;
公共静态void main(String[] args) {
新线程(()- {
synchronized (MyThread.class) {
尝试{
线程。睡眠(100);
} catch (InterruptedException e) {
抛出新的运行时异常(e);
}
内存=300;
}
System.out.println(修改了钱数);
}).start();
新线程(()- {
while (true) {
同步(MyThread.class)
{
如果(内存!=10000){
打破;
}
}
}
System.out.println(钱不见了);
}).start();
}
}不什么能解决?
线程获得锁清空变量副本拷贝最新的变量到副本中.
原子性并发工具类原子性多个操作是一个不可分割的整体(要么同时成功,要么同时失败)。
不稳定的不能保证原子性。
同步的可以保证原了操作
原子性_ AtomicIntegerAtomicInteger atom=new AtomicInteger(10);
系统。出去。println(atom。get());
系统。出去。println(atom。getandincrement());
系统。出去。println(atom。incrementandget());
系统。出去。println(atom。addandget(10));
系统。出去。println(atom。getandset(30));内存解析自旋锁国际体育仲裁法庭算法
国际体育仲裁法庭算法,三个操作数内存值v,旧的预期值一,要修改的值B
A==V,修改成功,V=BA!=V,修改失败,不操作重新获取现在最新的值(自旋)悲观锁和乐观锁同步-悲观锁
落下乐观锁
17-并发工具类散列表效率很低.线程访问时会锁住整张表
实现队列基本使用JDK1.5提供
并发哈希表1.7原理
只锁一部分,最多可以有16个线程同时访问
大数组创建,无法扩容
并发哈希表1.8原理国际体育仲裁法庭大数组用链表红黑树只锁部分
闭锁等待n个线程结束后再开始其它线程
公共类神话线索{
公共静态void main(String[] args)
引发中断的异常{
CountDownLatch CountDownLatch=new CountDownLatch(3);
新线程(()- {
for(int I=0;i 10i ) {
System.out.println(
Thread.currentThread().getName()I);
}
countdownlatch。倒计时();
}).start();
新线程(()- {
for(int I=0;i 100i ) {
System.out.println(
Thread.currentThread().getName()I);
}
countdownlatch。倒计时();
}).start();
新线程(()- {
for(int I=0;i 200i ) {
System.out.println(
Thread.currentThread().getName()I);
}
countdownlatch。倒计时();
}).start();
System.out.println(等待);
countdownlatch。await();
System.out.println(等待结束);
}
}旗语(信号量)公共类神话线索{
公共静态void main(String[] args)
引发中断的异常{
信号量信号量=新信号量(2);
for(int I=0;i 100i ) {
新线程(()- {
尝试{
旗语。获取();
System.out.println(获取通行证);
} catch (InterruptedException e) {
}
System.out.println(归还通行证);
semaphore.release()。
}).start();
}
}
}
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。