JAVA--多线程(概念)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/caoshiminYQS/article/details/79164739

进程与线程的区别:
进程 :有独立的内存空间,进程中的数据存放空间(堆空间和栈空间)是独立的
至少有一个线程。
线程:堆空间是共享的,栈空间是独立的,线程消耗的资源也比进程小,相互之间可以影响的,又成为轻型进程或进程元
java程序员的进程里至少包含主线程和垃圾回收线程(后台线程)


线程调度:
计算机通常只有一个cpu时,在任意时刻只能执行一条计算机指令,每一个进程只有获得CPU的使用权才能执行指令
所谓多进程并发运行,冲关上看,其实时各个进程轮流获得CPU的使用权,分别执行各自的任务
那么,在可运行池中,会有多个线程处于就绪状态等cpu,jvm就负责线程的调度


jvm采用的时抢占式调度,没有采用分时调度,因此可以造成多线程执行结果的随机性


java操作 


在java代码中如何去运行一个进程(简单简介,获取进程中的数据(IO))
方式1:Runtime类的exec方法:
方式2:ProcessBuilder的start方法:


主方法
Runtime runtime =Runtime.getRntime();
runtime.exec("notepad")
ProcessBuilder pb =new ProcessBuilder("notepad");
pb.start();


创建并启动线程 ,传统有两种方式
方式1:继承Thread 类;
方式2:实现Runnable接口;








线程类(java.lang.Thread):Thread和Thread的子类才能称之为线程。


Main方法运行,表示主线程


步骤
1.定义一个类A继承于java.lang.Thread类
2.在A类中覆盖Thread类中的run方法。
3.我们在run方法中编写需要执行的操作--->run方法里的,线程执行体。
4.在main方法(线程)中,创建线程对象,并启动线程
创建线程类: A类 a =new A类();
调用线程对象的start方法:a.start();//启动一个线程


注意:千万不要调用run方法,如果调用run方法好比是对象的调用方法,依然还是只有一个线程
并没有开启新的线程




方式2:实现Runnable接口
步骤
1.定义一个类A实现java.lang.Runnable接口
2.在A类中覆盖Runnable接口中的run方法
3.我们在run方法中编写需要执行的操作--->run方法里的,线程执行体
4.在main方法(线程)中没创建线程对象,并启动线程
创建线程对象   Thread t = new Thread();
调用线程对象start方法: t.start();




继承方式
1.java中类是单继承的,如果继承了Thread了,该类就不能再有其他的直接父类了
2.从操作上分析,继承方式更简单,获取线程的名字也简单(从操作上更简单)
3.从多线程共享同一个资源分析,继承方式不能做到
实现方式
1.java中类可以多实现接口,此时该类还可以继承其他类,并且还可以实现其他接口(设计上,更优秀)
2.从操作上分析,实现方式稍微复杂点,获取线程名字也比较复杂,得使用
Thread.currentThread()来获取当前线程的引用。
3.从多线程共享同一个资源上分析,实现方式可以做到。(共享资源上)




当多线程并发访问同一个资源对象时,可能出现线程不安全的问题




Thread.sleep();//当前线程睡10毫秒,当前线程休息着,让其他线程去抢资源,经常用来模拟网络延迟。


在线程的run方法上不能 使用throws来声明抛出异常,只能在方法中使用try -catch来处理异常
原因是:子类覆盖父类方法的原则,子类不能抛出新的异常,在Runnable接口中的run方法,都没有声明抛出异常


要解决多线程并发访问多一个资源的安全性问题
解决方案:
方式1:同步代码块
方式2:同步方法
方式3:锁机制(lock)


同步代码块:
synchronized(同步锁)
{
需要同步操作的代码
}
同步锁叫:同步监听对象/同步锁/同步监听器/互斥锁:
对象的同步锁只是一个概念,可以想象为在对象上标记了一个锁
注意:任何时候,最多允许一个线程拥有同步锁,谁拿到锁就进入代码块,其他的线程只能在外等着


同步监听对象,找多个线程共享的资源作为同步监听对象




同步方法:使用synchronized修饰的方法,就叫做同步方法,保证A线程执行该方法的时候,其他线程只能在方法外面等着
synchronized public void doWork(){ }


同步锁是谁:
  对于static方法,锁就是this
对于static方法,我们使用当前方法所在类的字节码对象()


不要使用synchronized修饰run方法,修饰之后某一个线程就执行完了所有的功能,好比是多个线程出现了串行
解决方案:把需要同步操作的代码定义在一个新的方法中,并且该方法使用synchronized
修饰,再在run方法中调用该新的方法即可;


synchronized的好与坏
好处:保证了多线程并发访问时的同步操作,避免线程的安全性问题
缺点:使用synchronized的方法/代码块的性能比不用要低一些 ,耗性能
建议:尽量减小synchronized的作用域。
面试题:
StringBuilder 和StringBuffer的区别?,StringBuffer类都加了synchronized
说说ArrayList和Vector的区别,HashMap和Hashtable的区别


但是synchronized的作用域太大了,损耗性能--->尽量减小synchronized的作用域
解决方案:使用双重检查锁机制


 

猜你喜欢

转载自blog.csdn.net/caoshiminYQS/article/details/79164739