首页 > 系统相关 >5、进程与线程

5、进程与线程

时间:2022-12-08 10:32:01浏览次数:41  
标签:run name Thread MyThread 线程 进程 ticket


进程与线程

1、  进程是程序的一次动态执行过程,它经历了从代码加载、执行到执行完毕的一个完整过程,这个过程也是进程本身从产生、发展到消亡的过程

2、  线程Thread是进程下更小的执行单位,同一进程下的多个线程可以同时执行,叫多线程

 

 

线程的使用

1、  线程可以通过继承Thread类或Runnable接口来实现,线程启动后会默认调用类中的run方法,如下

class MyThread extends Thread{
private String name;
public MyThread(String name){
this.name = name;
}
//线程默认调用的方法
publicvoid run(){
for(int i=1; i<=10; i++){
System.out.println(this.name +": "+ i);
}
}
}

 

2、  使用Thread定义线程,并使用

class MyThread extends Thread{
private String name;
public MyThread(String name){
this.name = name;
}
publicvoid run(){
for(int i=1; i<=10; i++){
System.out.println(this.name +": "+ i);
}
}
}

publicclass hello{
publicstaticvoid main(String args[]){
MyThread t1 =new MyThread("thread one");
MyThread t2 =new MyThread("thread two");
t1.run();
t2.run();
}
}

执行后发现,程序在按顺序执行,显然多线程并没有启动。要启动线程,需要将t1.run()与t2.run()修改为t1.start()和t2.start()才可以,start表示启动线程,而线程启动后会直接去调用类中的run()方法。

 

3、  使用Runnable定义线程,并使用

class MyThread implements Runnable{
private String name;
public MyThread(String name){
this.name = name;
}
publicvoid run(){
for(int i=1; i<=10; i++){
System.out.println(this.name +": "+ i);
}
}
}

publicclass hello{
publicstaticvoid main(String args[]){
MyThread t1 =new MyThread("thread one");
MyThread t2 =new MyThread("thread two");
Thread td1 =new Thread(t1); //启动仍需通过Thread对象
Thread td2 =new Thread(t2); //启动仍需通过Thread对象
td1.start();
td2.start();
}
}

Runnable接口定义的线程如果要启动仍然需要通过Thread对象,这是主要的区别

 

4、  Thread类与Runable接口的区别

一个类如果继承了Thread类,则多线程不适合进行资源共享;而实现了Runnable接口则可以方便的实现资源共享

可以通过Thread.currentThread().getName()获取当前线程对象和线程名称

 

继承Thread类如下,共5张票,但是每个线程都卖出了5张票,这是不对的

class MyThread extends Thread{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
if(ticket>0){
System.out.println(Thread.currentThread().getName()
+" sold ticket: "+ ticket--);
}
}
}
}

publicclass hello{
publicstaticvoid main(String args[]){
//声明了两个线程对象,两个线程都拥有自己单独的资源
MyThread t1 =new MyThread();
MyThread t2 =new MyThread();
//分别启动两个线程,因为两个线程的资源不是共享的
//所以每个线程会发5张票,这就不对了
t1.start();
t2.start();
}
}

实现Runnable接口的类如下,共5张票,两个线程共输出5张票,结果正确

通过Thread.currentThread()可获取当前线程对象

通过Thread.currentThread().getName()可以获取当前线程对象名

class MyThread implements Runnable{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
if(ticket>0){
System.out.println(Thread.currentThread().getName()
+" sold ticket: "+ ticket--);
}
}
}
}

publicclass hello{
publicstaticvoid main(String args[]){
//声明一个资源对象
MyThread t1 =new MyThread();
//启动两个线程,两个线程共享t1内的资源,实现资源共享
Thread td1 =new Thread(t1);
Thread td2 =new Thread(t1);
td1.start();
td2.start();
}
}

 

 

JVM、进程与线程

1、  Java编写的程序都运行在jvm中,每一个程序启动时,都会启动一个JVM,这个JVM实际上就是进程

2、  一个java程序至少启动两个线程,一个是main函数线程,一个是程序的垃圾收集线程

 

 

线程状态

1、  创建:Thread t =new Thread();

2、  就绪:t.start();线程启动后就进入操作系统排队,排到了就调用run方法运行

3、  运行:t.run(); 由系统调用运行

4、  堵塞:sleep();suspend();wait()时,线程暂停执行

5、  死亡:stop()或run()结束时

 

 

线程同步与死锁

1、  实现了Runnable接口的类,类中的属性由多个线程共享,这时如果多个线程同时操作一个资源时就会出问题,所以出现了线程同步问题,如下

class MyThread implements Runnable{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
if(ticket>0){
try{
//sleep后线程紧密排队,导致资源争抢
Thread.sleep(300);
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sold ticket: "+ ticket--);
}
}
}
}

publicclass hello{
publicstaticvoid main(String args[]){
MyThread t1 =new MyThread();
Thread td1 =new Thread(t1);
Thread td2 =new Thread(t1);
td1.start();
td2.start();
}
}

 

2、  线程同步,指同一时间内,只允许一个线程对资源进行操作,其它线程排队直到前一个线程完成

 

3、  同步代码块,synchronized(同步对象){需同步代码},如下

class MyThread implements Runnable{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
//同步其中的代码块,防止资源争抢,一般使用this,意思是对当前对象进行同步
//同一时间只允许一个线程访问this(当前)对象,而this对象中包含共享资源ticket
synchronized(this){
if(ticket>0){
try{
Thread.sleep(300);
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sold ticket: "+ ticket--);
}
}
}
}
}

 

4、  同步方法,锁定了该方法同一时间只能有一个线程对其进行调用,如下

class MyThread implements Runnable{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
sale();
}
}
//同步方法,
privatesynchronizedvoid sale(){
if(ticket>0){
try{
Thread.sleep(300);
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sold ticket : "+ ticket--);
}
}
}

 

 

同步与死锁

1、  当需要解决资源共享时,要使用同步来解决

2、  当同步过多时,会出现死锁问题

 

标签:run,name,Thread,MyThread,线程,进程,ticket
From: https://blog.51cto.com/u_15906220/5920666

相关文章

  • Python3 多线程并发处理的返回值收集
    库函数threading背景去查询python3多线程,可以找到一大堆关于threading库的博客教程,但是多数是几个线程执行同一个函数(他们博客里各个线程传入的函数参数不同),且没有......
  • Java线程中断机制
    在阅读AQS源码以及juc包很多基于AQS的应用源码过程中,会遇到很多interrupted相关的方法,这里复习一下java线程中断相关。要点:使用interrupt()中断一个线程,该方法只是标记中......
  • 8 网络&多线程
    HeadFirstJava和AcWingJava课程做的总结8。所有网络运作的低层细节都已经由java.net函数库处理掉了。传送与接收网络上的数据只不过是链接上使用不同的链接串流的输......
  • 进程管理
    1.什么是进程?进程(Process)是一个具有独立功能的程序关于某个数据集合的一次运行活动,是系统进行资源分配和调度的一个独立单位或者说是基本单位.1.1进程的结构控制......
  • 线程池ThreadPoolTaskExecutor的同步及异步使用
    参考信息本人参考的是这一篇,描述方面比本人好得多:springboot线程池的使用和扩展VisiableThreadPoolTaskExecutor背景:简略记一下,笔记:目标是想在springboot服务下,自......
  • 线程池中CompletionService的应用
    当使用ExecutorService启动了多个Callable后,每个Callable会产生一个Future,我们需要将多个Future存入一个线性表,用于之后处理数据。当然,还有更复杂的情况,有5个生产者线程,每......
  • java面试(多线程)
    1. Callable、Future、FutureTash详解Callable与Future是在JAVA的后续版本中引入进来的,Callable类似于Runnable接口,实现Callable接口的类与实现Runnable的类都是可以被线程......
  • JUC6 中断机制与线程通信三种让线程等待和唤醒的方法:
    1.线程中断1.1什么是线程中断①.一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止,所以,Thread.stop、Thread.suspend、Thread.resume都已经被废......
  • JUC5 多线程锁(下)
    1.​​synchronize​​锁升级:无锁,偏向锁,轻量锁,重量锁(看病:社区医院->三甲医院)1.1 概述按照获得锁和释放锁的性能消耗,锁的分类:1.无锁状态2.偏向锁:不进行​​CAS​​,测......
  • JUC4 多线程锁(上)
    1.乐观锁和悲观锁①.悲观锁什么是悲观锁?认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改适合写操作多的场......