【JAVA】Java多线程

线程基本概念
线程是什么?
一个线程就是一个程序内部的一条执行路径,一个进程可以包含多个进程。
当程序启动运行时,就自动产生了一个线程,主函数main就是在这个线程上运行的,当不再产生新的线程时,程序就是单线程,只有一条执行路径。

进程是什么?
计算机中的程序关于某数据集合上的一次运行活动。可以理解成每个独立运行的程序就是一个进程,进程也就是“正在运行的程序”。

线程和进程的区别:
每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,线程可以看成是轻量级的进程,同一线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程的切换开销小。

什么是多进程:
在操作系统中同时执行多个程序

什么是多线程:
在同一个应用程序中有多个执行路径,但是在一个时间点上,只用一个线程在该CPU 上运行。

多线程的创建和启动
创建多线程有两种方法:继承Thread类和实现Runnable 接口

使用Thread类创建多线程
Thread 类是java 中一个线程类,线程可以通过继承java.lang.Thread的类来实现。
java 程序在启动时由一个主方法main{}创建了一个线程,我们称之为主线程。
我们可以通过创建Thread的实例来创建线程,必须通过调用Thread 类的start方法启动一个线程,

public class A { 
   public static void main(String[] args) {  
        B b=new B();        
	    b.start();        
		while(true)     
		{         
	        System.out.println("main thread is running.");    
		}   
	}  
}   

class B extends Thread {  
       public void run()  
	   {   
	      while(true)   
		  {                                                      System.out.println(Thread.currentThread().getName()+" is running.");    
		  }   
	   }  
    }

thread 类有一个start方法,该方法为线程启动,会去执行继承Thread类的run 方法。
要将一段代码在一个新的线程上运行,该代码应该在一个类的run函数中,并且run函数所在的类是Thread类的子类。

一个thread类的对象就代表一个线程,而且只能代表一个线程

使用Runnable 接口创建多线程
Runnable接口有一个run()方法,用于定义线程运行体,所以我们只需要重写这个方法就可以。

public class A { 
   public static void main(String[] args) {  
        B b=new B();        
		Thread t=new Thread(b);   //创建一个线程,b为Runnable 接口对象
		 //线程启动,会去调用run方法,不能直接调用run方法,那不是启动新线程,而是方法调用
		t.start();        
		while(true)     
		{         
	        System.out.println("main thread is running.");    
		}   
	}  
}   

class B implements Runnable {  
       public void run()  
	   {   
	      while(true)   
		  {                                                      System.out.println(Thread.currentThread().getName()+" is running.");    
		  }   
	   }  
    }

线程的状态控制
当我们的线程被new出来的时候只是一个对象,当我们调用start 的方法时,就进入就绪状态,当被调度到cpu的时候才进入运行状态,在运行的过程中如果突发事件导致阻塞,则进入阻塞状态,阻塞解除之后进入就绪状态,线程只能从就绪态到运行状态。
这里写图片描述

线程控制的基本方法:
isAlive():判断线程是否还活着,即线程是否还未终止
getPriority():获得线程的优先级数值。
setPriority():设置线程的优先级数值。
Thread.sleep():当前线程睡眠指定毫秒数
join:合并某线程
yield:让出cpu,当前线程进入就绪队列等待调度。
wait() :当前线程进入对象的wait pool中
notify()/notifyAll():唤醒对象的wait pool中的一个/所有等待线程。

sleep:
public static void sleep(long millis) throws interruptedException

 public class TestInterrupt{
     public static void main(String[] args){
       MyThread thread=new MyThread();
       thread.start();
       try{Thread.sleep(100000);}
       catch(InterruptedException e){}
       thread.interrupt();  //打断
}
}

class MyThread extends Thread{
   
}

线程同步
多个线程之间访问同一份资源的时候,只能有一个线程访问该资源,其他线程都不可以对该资源进行访问,直到该线程结束, 其他线程才能访问该资源。

没有使用锁的代码:

public class TT implements Runnable{
    int b=100;

    public synchronized void m1() throws Exception{
        b=1000;
        Thread.sleep(5000);
        System.out.println("b="+b);
    }
    public void m2() throws Exception{
       Thread.sleep(2500);
       b=2000;
    } 
   
    public void run(){
          try{
             m1();
       }catch(Exception e){
        e.printStackTrace();
       }
     }
     
     public static void main(String[] args) throws Exception{
         TT tt=new TT();
         Thread t=new Thread(tt);
         t.start();
      
         Thread.sleep(1000);
         tt.m2();
     }
}

当前程序有两个线程对象,一个主线程,一个t.start线程,当执行t.strat()时候,t线程会去执行m1,t1线程获得了这把锁,此时b=1000,其他线程不能再来执行这个方法,但是其他线程可以去执行别的方法,在t1睡眠5秒时,tt线程去执行m2 方法,此时b=2000,然后t线程再去打印b, 再去所有打印出来的b是2000。

假如给m2 方法也加上锁,如下

public class TT implements Runnable{
 int b=100;

 public synchronized void m1() throws Exception{
    b=1000;
    Thread.sleep(5000);
    System.out.println("b="+b);
}
public synchronized void m2() throws Exception{
   Thread.sleep(2500);
   b=2000;
} 

public void run(){
      try{
         m1();
   }catch(Exception e){
    e.printStackTrace();
   }
 }
 
 public static void main(String[] args) throws Exception{
     TT tt=new TT();
     Thread t=new Thread(tt);
     t.start();
  
     Thread.sleep(1000);
     tt.m2();
 }
}

本程序有两个线程,首先是t调用m1方法,给对象加锁,此时tt不能再为该对象加锁,只能等待t执行完,才能对m2加锁,执行m2的方法,某一对象在某一时刻只能被一个线程加锁, synchronized 锁定当前对象,某一时刻只能锁定当前对象的一个方法,另外一个加锁的方法不能再去锁定当前对象。每一个对象只有一把锁,谁拿到这把锁谁就执行该方法,其他的对象不能拿到该对象的这把锁。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 35
    评论
评论 35
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诗琪小姐姐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值