CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛

实现多线程的三种方法(干货满满)java实现多线程的三种方法,涨姿势了!原来这才是多线程正确实现方式,

1.java中实现多线程的几种方法

Java内存模型

2.java多线程csdn

线程同步线程同步机制是一套适用于协调线程之间的数据访问机制,该机制可以保障线程安全java平台提供的线程同步机制包括:锁、volatile关键字、final关键字,static关键字、以及相关API如object.wait/object.notify

3.Java实现多线程的方法

锁概述线程安全问题的产生前提是多个线程并发访问共享数据,将多个数据对共享数据的并发访问,转化为串行访问,即共享数据只能被一个线程访问,锁就是这种思路线程访问数据时必须先获得锁,获得锁的线程称为锁的持有线程,一个锁一次只能被一个线程持有,持有线程在获得锁之后和释放锁之前锁执行的代码称之为临界区。

4.java多线程菜鸟教程

锁具有排它性(Exclisive),即一个锁只能被一个线程持有,这种锁称为排它锁或者互斥锁。

5.java中实现多线程一般使用两种方法

JVM部分把锁分为内部锁和显示锁,内部锁通过Synchronized关键字实现,显示锁通过java.concurrent.locks.Lock接口实现类实现的锁的作用锁能够实现对共享数据的安全,保障线程的原子性,可见性与有序性。

6.java多线程使用

锁是通过互斥保障原子性,一个锁只能被一个线程持有,这就保证了临界区的代码一次只能被一个线程执行,使得临界区代码所执行的的操作自然而然的具有不可分割的特性,既具备了原子性好比一条路段所有车辆都在跑,并发执行,在经过某一个路段的时候,多车道变为一车道,一次只能通过一辆车,由并发执行改为串行执行。

7.Java多线程实现

可见性是通过写线程冲刷处理器的缓存和读线程刷新处理器缓存这两个动作,锁的获得隐含着刷新处理器缓存的动作,锁的释放隐含着冲刷处理器缓存的动作锁能够保障有序性,写线程在临界区所执行的临界区看来像是完全按照源码顺序执行的。

8.Java多线程方法

锁的相关概念可重入性:一个线程持有该锁的时候能够再次/多次申请该锁如果一个线程持有一个锁的时候,还没有释放,但还能够继续成功申请该锁,称该锁可重入,反之锁的争用与调度java中内部锁属于非公平锁,显示锁支持非公平锁和公平锁。

9.java实现多线程的四种方式

锁的粒度一个所可以保护的共享数据的数量大小称为锁的粒度锁保护共享数据量大,称为锁粒度粗,否则称为粒度细锁的粒度过粗会导致线程在申请锁时会进行不必要的等待,锁粒度过细会增加锁调度的开销比如银行有一个柜台一个员工可以办理开卡、销户、取现、贷款那么所有人都只能去这个柜台办理业务,会需要很长的等待时间。

10.JAVA实现多线程

但是如果把业务细分,一个业务一个柜台,这时候增加了银行的开销,需要三个员工内部锁:SynchronizedJava中每一个对象都有一个与之关联的内部锁,这种锁也叫监视器,是一种排它锁,可以保障原子性、可见性、排它性。

Synchronized(对象锁) { 同步代码块,可以在同步代码块中访问共享数据 } 修饰实例方法称为同步实例方法,修饰静态方法称为同步静态方法Synchronized同步代码块publicclass。

SynchronizedLock { publicstaticvoidmain(String[] args) { SynchronizedLock synchronizedLock=

new SynchronizedLock(); for (int i = 0; i <2 ; i++) { new Thread(new RunnableThread()) { @

Override publicvoidrun() { synchronizedLock.mm(); } }.start(); } }

publicvoidmm() { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+

“–>”+i); } } } 两个线程的代码都在并发执行

现在要打印的时候进行同步,同步的原理线程在执行的时候要先要获得锁publicclassSynchronizedLock{ publicstaticvoidmain(String[] args){ SynchronizedLock synchronizedLock=

new SynchronizedLock(); for (int i = 0; i <2 ; i++) { new Thread(new RunnableThread()) {

@Overridepublicvoidrun(){ synchronizedLock.mm();//使用锁的对象是synchronizedLock对象 } }.start(); } }

publicvoidmm(){ synchronized (this)//this作为当前对象 { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+

“–>”+i); } } } }

因为Synchronized内部锁是排它锁,一次只能被一个线程持有,现在是Thread-0先取得锁对象,Thread-1在等待区等待Thread-0执行完毕释放锁,Thread-1获得锁再执行锁对象不同不能实现同步。

publicclassSynchronizedLock{ publicstaticvoidmain(String[] args){ SynchronizedLock synchronizedLock=

new SynchronizedLock(); SynchronizedLock synchronizedLock2=new SynchronizedLock();

new Thread(new RunnableThread()) { @Overridepublicvoidrun(){ synchronizedLock.mm();

//使用锁的对象是synchronizedLock对象 } }.start(); new Thread(new RunnableThread()) {

@Overridepublicvoidrun(){ synchronizedLock2.mm();//使用锁的对象是synchronizedLock对象 } }.start(); }

publicvoidmm(){ synchronized (this)//this作为当前对象 { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+

“–>”+i); } } } }

因此想要同步必须使用同一个锁对象使用常量作为锁对象publicclassSynchronizedLock{ publicstaticvoidmain(String[] args){ SynchronizedLock synchronizedLock=

new SynchronizedLock(); SynchronizedLock synchronizedLock2=new SynchronizedLock();

new Thread(new RunnableThread()) { @Overridepublicvoidrun(){ synchronizedLock.mm();

//使用锁的对象是synchronizedLock对象 } }.start(); new Thread(new RunnableThread()) {

@Overridepublicvoidrun(){ synchronizedLock.mm();//使用锁的对象是synchronizedLock对象 } }.start(); }

publicstaticfinal Object obj=new Object(); publicvoidmm(){ synchronized (obj)//常量作为当前对象 {

for (int i = 0; i “

+i); } } } } 同步实例方法使用synchronized修饰实例方法,同步实例方法,默认使用this作为锁对象publicclassSynchronizedLock

{ publicstaticvoidmain(String[] args){ SynchronizedLock synchronizedLock=new SynchronizedLock();

new Thread(new RunnableThread()) { @Overridepublicvoidrun(){ synchronizedLock.mm(); } }.start();

new Thread(new RunnableThread()) { @Overridepublicvoidrun(){ synchronizedLock.mm2(); } }.start(); }

//同步实例方法publicsynchronizedvoidmm(){ for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+

“–>”+i); } } publicvoidmm2(){ synchronized (this)//常量作为当前对象 {

for (int i = 0; i “

+i); } } } } 同步静态方法使用synchronized修饰静态方法,同步静态方法,默认运行时使用SynchronizedLock class作为锁对象

publicclassSynchronizedLock{ publicstaticvoidmain(String[] args){ SynchronizedLock synchronizedLock=

new SynchronizedLock(); new Thread(new RunnableThread()) { @Overridepublic

voidrun(){ synchronizedLock.mm2(); } }.start(); new Thread(

new RunnableThread()) { @Overridepublicvoidrun(){ SynchronizedLock.mm();

//使用锁的对象是SynchronizedLock.class } }.start(); } //同步静态方法publicsynchronized

staticvoidmm(){ for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+

“–>”+i); } } publicvoidmm2(){ synchronized (SynchronizedLock.class)//常量作为当前对象

{ for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+

“–>”+i); } } } } 同步代码块和同步方法如何选择publicclassSynchronizedLock { publicstatic

voidmain(String[] args) { SynchronizedLock synchronizedLock=new SynchronizedLock(); new

Thread(new RunnableThread()) { @Override publicvoidrun() {

try { synchronizedLock.mm2(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start();

new Thread(new RunnableThread()) { @Override publicvoidrun() {

try { synchronizedLock.mm2();//使用锁的对象是SynchronizedLock.class } catch

(InterruptedException e) { e.printStackTrace(); } } }.start(); }

//同步实例方法 锁的粒度粗 执行效率低public synchronized voidmm() throws InterruptedException { long starttime= System.currentTimeMillis(); System.

out.println(“start”); Thread.sleep(3000); for (int i = 0; i <100 ; i++) { System.

out.println(Thread.currentThread().getName()+”–>”+i); } System.out.println(“end”);

long Endtime= System.currentTimeMillis(); System.out.println(Endtime-starttime); } //同步代码块 锁的粒度细 并发效率高

publicvoidmm2() throws InterruptedException { System.out.println(“start”); Thread.sleep(

3000); synchronized (this)//常量作为当前对象 { for (int i = 0; i <100 ; i++) { System.

out.println(Thread.currentThread().getName()+”–>”+i); } } System.out.println(

“end”); } } 在执行同步方法的时候,两次线程调用每次都需要休眠三秒,而同步代码块同时启动线程都先准备三秒,效率比较高脏读publicclassTest06{ publicstatic

voidmain(String[] args)throws InterruptedException { User user=new User(); SubThread subThread=

new SubThread(user); subThread.start(); user.GetName(); } staticclassSubThread

extendsThread{ public User user; publicSubThread(User user){ this.user=user; }

@Overridepublicvoidrun(){ user.SetValue(“ww”,”456″); } } staticclassUser{

private String name=”ylc”; private String pwd=”123″; publicvoidGetName(){ System.out.println(Thread.currentThread().getName()+

“==>”+name+”密码”+pwd); } publicvoidSetValue(String name,String pwd){ System.out.println(

“原来为为name=”+this.name+”,pwd=”+this.pwd); this.name=name; this.pwd=pwd; System.out.println(

“更新为name=”+name+”,pwd=”+pwd); } } }

在修改数据还没有完成的时候,就读取到了原来的数据,而不是修改之后的出现脏读的原因是对共享数据的修改和读取不同步引起的解决办法是对修改和读取的方法进行同步方法上加上synchronized关键字

线程出现异常释放锁假如在同步方法中,一个线程出现了异常,会不会没有释放锁,其他在等待的线程就在一直等待,论证:publicclassSynchronizedLock{ publicstaticvoid

main(String[] args){ SynchronizedLock synchronizedLock=new SynchronizedLock(); new Thread(

new RunnableThread()) { @Overridepublicvoidrun(){ synchronizedLock.mm(); } }.start();

new Thread(new RunnableThread()) { @Overridepublicvoidrun(){ synchronizedLock.mm2(); } }.start(); }

//同步实例方法publicsynchronizedvoidmm(){ for (int i = 0; i <100 ; i++) { if(i==50) { Integer.parseInt(

“abc”);//异常设置 } System.out.println(Thread.currentThread().getName()+”–>”+i); } }

publicvoidmm2(){ synchronized (this) { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+

“–>”+i); } } } }

同步过程中线程出现异常,会自动释放锁对象,以供下一个线程继续执行死锁多线程中可能需要使用多个锁,如果获取锁的顺序不一致,可能导致死锁publicclassText06_5{ publicstatic。

voidmain(String[] args){ SubThread subThread=new SubThread(); SubThread subThread2=new

SubThread(); subThread.setName(“a”); subThread2.setName(“b”); subThread.start();subThread2.start(); }

staticclassSubThreadextendsThread{ privatestaticfinal Object lock1=new Object(); private

staticfinal Object lock2=new Object(); @Overridepublicvoidrun(){ if(“a”.equals(Thread.currentThread().getName())) {

synchronized (lock1) { System.out.println(“a 线程 lock1获得了锁,再需要获得lock2”

); synchronized (lock2) { System.out.println(

“a 线程 lock2获得了锁”); } } } if(“b”.equals(Thread.currentThread().getName())) {

synchronized (lock2) { System.out.println(“b 线程 lock2获得了锁,再需要获得lock1”

); synchronized (lock1) { System.out.println(

” b 线程 lock1获得了锁”); } } } } } }

程序还在运行,却进入了卡死状态,a线程得到了lock1,要想把该线程释放的执行下面的代码获取lock2,而lock2被b线程获取无法释放,出现了鹬蚌相争的情况避免死锁:当需要获得锁时,所有线程获得锁的顺序一致,a线程先锁lock1,再锁lock2,b线程同理,就不会出现死锁了。

原文链接:https://www.cnblogs.com/cg-ww/p/14491507.html?utm_source=tuicool&utm_medium=referral如果觉得本文对你有帮助,可以转发关注支持一下

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
相关推荐
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容