java 多线程

进程和线程

  • 进程,是指计算机运行的一个程序,每个进程都有独自的代码和数据空间,进程间的切换会有很大的开销
  • 线程,一个程序内部的多个控制流一个进程可以包括多个线程,线程之间切换开销很小
  • 多进程,操作系统可以同时运行多个进程(程序)
  • 多线程,在同一个程序中有多个线程执行

 多线程实现的两种方式

继承Thread类,重写run()方法

public class 类名 extends Thread{
    //重写run方法
    @Override
    public void run(){
        //该线程实现的功能
    }
}

开启线程:线程类对象名.start();

实现Runnable接口

public class 类名 implements Runnable{
    //重写run()方法
    @Override
    public void run(){
        //该线程实现的功能
    }
}

开启线程:

  1. 先创建实现Runnable接口的类的对象
  2. 然后创建爱你Thread对象 Thread 对象名 = new Thread(Runnable对象);
  3. Thread对象调用start()方法

两种方式的比较

  • 继承、接口(可以更好的扩展)
  • 两种方式本质上都是调用了Thread的run方法

线程的生命周期

线程独对象从start开始到结束,期间存在不同的状态:

  • 创建new
  • 就绪状态,线程对象调用start方法后
  • 运行状态,被线程调度器执行
  • 阻塞状态,当运行中的线程产生阻塞事件时,进入阻塞状态,阻塞状态结束后,进入就绪状态
  • 停止状态,线程运行完成

线程中的主要方法

  • sleep(millis) ,Thread类的静态方法,接受一个以毫秒为单位的参数,表示让线程休眠millis毫秒
    如:Tread.sleep(100);//让当前线程休眠100毫秒
  • join() ,在一个线程A中使用另一个线程对象B调用join()方法,表示线程A等待另一个线程B结束后再继续执行A线程
  • yield(),让出cpu,进入就绪队列
  • isAlive(),判断线程是否存活
  • wait(),让该对象上的当前线程进入等待,直到其他线程调用此对象的notify()方法或notifyAll()方法
  • notify(),唤醒在此对象监视器上等待的单个线程
  • notifyAll(),唤醒在次对象监视器上等待的所有线程

线程的优先级

  • 就绪状态的线程,如果有多个,线程调度器在选择就绪状态的线程时,优先选择优先级高的运行
  • java线程优先级公有十级1~10,10最高,1最低,默认为优先级为5

Thread.MAX_PRIORITY   //10

Thread.NOMAL_PRIORITY   //5

Thread.MIN_PRIORITY   //1

使用getPriority()方法获取优先级,setPriority()方法设置优先级

线程的同步

如果涉及到多个线程操作同一个资源,会产生问题。

同步是指多个线程同时操作同一个资源时,需要排队操作,保证同一个时间点只有一个线程操作这个资源。

至少有一个线程修改这个资源时,需要线程同步。如果多个线程只进行读取资源,则不需要线程同步。

线程同步在java中使用关键字synchronize,主要分为两种形式:

  • synchronize修饰一段代码块
    • 使用synchronize修饰对同一资源操作的代码块,需要传入一个对象,可以传入this代表当前对象
    • synchronize(对象){//代码块}
    • 优点:可以只选择需要同步的少量代码进行加锁,释放锁速度快,可以获取其他对象的锁
    • 缺点:不易于查看哪些方法是加锁的
  • synchronize修饰一个方法
    表示同一时刻只能有一个线程来调用该方法,其他线程在上一个线程调用完成之前不能调用相同对象的此方法
    • 优点:可以明显地知道哪些方法是同步的
    • 缺点:如果方法中有其他的不需要同步的代码,仍然需要执行完整个方法后才会释放同步锁,且只能获取相同对象的锁

死锁状态

两个线程之间互相等待对方的锁,造成死锁状态

线程锁示例

实现奇数。偶数交替输出

Thread1类,实现奇数的输出:

public class Thread1 implements Runnable{
	private Object obj;
	public Thread1(Object obj) {
		this.obj = obj;
	}
	@Override
	public void run() {
		synchronized (obj) {//获取相同对象的锁
			//输出奇数
			for(int i = 1;i <= 100;i+=2) {
				System.out.println("Thread1:"+i);
				obj.notify();//唤醒该对象上的其他线程
				try {
					obj.wait();//本线程进入等待
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}

}

Thread2类,实现偶数的输出:

public class Thread2 implements Runnable{
	
	private Object obj;
	public Thread2(Object obj) {
		this.obj = obj;
	}
	@Override
	public void run() {
		synchronized (obj) {//获取相同对象的锁
			//输出偶数
			for(int i = 2;i <= 100;i+=2) {
				System.out.println("Thread2:"+i);
				obj.notify();//唤醒该对象上的其他线程
				try {
					obj.wait();//本线程进入等待
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		
	}

}

测试类:

public class Test1 {

	public static void main(String[] args) {
	
		Object obj = new Object();
		Thread1 run1 = new Thread1(obj);//传入相同的对象
		Thread2 run2 = new Thread2(obj);
		Thread t1 = new Thread(run1);
		Thread t2 = new Thread(run2);
		t1.start();
		t2.start();

	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值