java基础:线程与进程;线程的分工,协作,互斥;volatile关键字

这次就分享一下关于线程进程的经验吧,不太高深,但还是希望对各位有所帮助!

一.进程线程的概念

线程:是程序执行中的单个顺序流程。
进程:一个执行中的程序,是操作系统对其进行资源分配的最小单位。
多线程:一个进程可以同时执行多条线程,进行不同的任务。
一个进程通常会包含多个线程。

为什么需要多线程呢?当我们做一件事的时候,如果一件一件的线性去做,就会浪费许多时间,因为有些步骤可以在其他某些步骤执行的时候同步执行,这样才能保证效率。多线程就是如此。
举个简单的例子:
在这里插入图片描述

在这里插入图片描述
下面是代码的具体实现:

public class Run implements Runnable{
	public static void main(String[] args){
		Run r=new Run();
		Thread a= new Thread(r); //
		System.out.println("烧水泡茶工序:");
		System.out.println("1、洗水壶");
		System.out.println("2、烧水");
		a.start();
		try {
			a.join();
		} 
		catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("6、泡茶");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub 
		System.out.println("3、洗茶壶");
		System.out.println("4、洗茶杯");
		System.out.println("5、拿茶叶");
	}
}

二.资源分配

进程:每个进程都有自己独立的内存空间和系统资源,其内部数据和状态是独立的。
线程:同类的多个线程共享一块内存空间和系统资源,其本身的数据只有微处理器的寄存器数据以及供程序执行时使用的堆栈。
在这里插入图片描述

所以操作系统执行线程时负荷较小,线程也被称为轻负荷进程

提到线程,通常会从三个方面分析:分工(创建)协作(同步通信)互斥(资源共享)

三.线程的创建

(1)直接继承Thread类覆盖run方法。

public class mythread extends Thread{
   public static void main(String args[]){
       Thread t = new Thread();
       t.start();
   }
   public void run(){
      System.out.println("thread run");
   }
}

(2)实现runable接口并将实现类对象作为参数传给Thread类的构造方法。

public class mythread implements Runable{
   public static void main(String args[]){
     mythread t = new mythread():
     Thread a = new Thread(t);
     a.start();
   }
   public void run(){
     System.out.println("thread run");
     }
}

两种方法的比较:
(1)直接继承thread类方法编写简单,可以直接操控该线程。
(2)实现runable接口可以让多个线程共享实现类的资源。

四.线程的控制和调度

一个线程从创建,运行到消亡的过程为线程的生命周期。
线程具有五种状态:
(1)创建状态:仅是一个对象,系统还未分配资源给它。
(2)可运行状态:start方法启动一个线程之后,系统分配了除CPU以外的所有资源。
(3)运行中状态:系统调度系统选中了一个可运行状态的线程,使其占有CPU转化为运行中状态。
(4)阻塞状态:一个运行中状态遇到特殊情况让出CPU暂时中止执行。
(5)死亡状态:线程结束,到达run方法的末尾,或者线程抛出一个未捕获的异常或错误。

在这里插入图片描述

线程的调度和优先级

在这里插入图片描述

抢占式调度:高优先级的线程采用独占方式调度,除非其执行完毕,或者进入阻塞状态,低优先级的线程才能获得执行权。当多个处于可运行状态的线程中有高优先级的线程,高优先级的线程立即执行,即便是处于运行中状态的线程也要转为可运行状态,让高优先级的线程执行。

时间片轮转调度:多个优先级相同的线程处于可运行状态时,每个线程轮流获得一个时间片执行,当时间片过去时,即使没有执行完毕,也要让出CPU,等待下一个时间片的到来。

五.线程的互斥

多线程环境下,当多线程共同访问同一个资源时,容易出现线程安全问题。

所以要用到volatile修饰符和synchronized关键字

(1)volatile修饰符:将被共享的变量声明为 valatile,指示这个JVM是不稳定的,每次使用它都有到主存中进行读取。
(2)synchronized:Java引入监视器来保证数据共享的同步性,任何对象都可作为一个监视器,当被synchronized关键字修饰时,该对象就成为监视器。

多个线程对共享资源进行操作的时候容易起冲突,这些易起冲突的代码块成为临界区。在临界区中引入监视器,并且用synchronized使多个线程同步起来,只有获得监视权的线程才能进入临界区,只能有一个线程独占执行临界区的代码块,从而避免多个线程直接的冲突。

在这里插入图片描述

六.线程的协作(同步通信)

在这里插入图片描述

在这里插入图片描述

七.线程的应用场景

1、大多数WEB服务器处理客户端的服务请求就采用的是多线程模式,每个客户相当于激发该服务的一个处理线程。

2、当处理一个执行时间较长的请求时,一般让一个线程进行处理,而另一个线程进行控制,这样,如果用户需要选择“取消”时,可以强迫处理线程停止运行。

3、通讯时,可以让一个线程负责接收,另一个负责发送,这样可以实现通讯的“全双工”。

4、对WEB服务器进行测试时,可以在一个进程中产生多个线程,每个线
程相当于一个客户对WEB服务器进行访问,从而可以编写压力测试工具。
但要注意的是,对于一个进程,不要产生过多的线程,否则线程之间的切
换将会造成效率非常低下。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个基于Java的使用synchronized关键字解决进程间同步和互斥问题的示例代码: ``` public class MyClass { private int count = 0; public synchronized void increment() { count++; } public synchronized void decrement() { count--; } public synchronized int getCount() { return count; } } ``` 在这个示例中,MyClass类有一个count属性,用于记录一个计数器的值。increment()方法和decrement()方法分别用于增加和减少计数器的值,getCount()方法用于获取计数器的当前值。 这些方法都使用了synchronized关键字来实现同步和互斥。在使用synchronized关键字时,需要将需要同步的代码块或方法用synchronized关键字进行修饰。在这个示例中,所有的方法都使用了synchronized关键字,因此同一时刻只有一个线程可以访问这些方法。 使用这个示例的方法很简单,在多个线程中创建一个MyClass的实例,然后分别调用increment()和decrement()方法即可。在多个线程同时访问这个对象时,synchronized关键字会自动实现同步和互斥,保证计数器的值正确无误。 需要注意的是,在使用synchronized关键字时,需要避免死锁和竞态条件等问题。死锁是指多个线程互相等待对方释放资源的情况,可以通过避免重复获取锁、按照固定的顺序获取锁等方法来避免死锁。竞态条件是指多个线程同时访问共享资源,并且对资源的访问顺序不确定的情况,可以通过使用volatile关键字、使用同步容器等方法来避免竞态条件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值