Java中的多线程

1 创建多线程的几种方式

线程的创建常用的几种方式:

  • 创建一个Thread类或者一个Thread子类的对象。
  • 创建一个实现Runnable接口的类的对象。

1.1 通过Thread类创建线程

1.1.1 Thread类

首先来看下Thread类:Thread是一个线程类,位于java.lang包下。

在这里插入图片描述

Thread类的常用方法:
在这里插入图片描述

1.1.2 创建线程

通过继承Thread类的方式创建线程类,重写run()方法。

示例代码如下:

package com.imooc.thread;
class MyThread extends Thread{
	public void run(){
		System.out.println(getName()+"该线程正在执行!");
	}
}

public class ThreadTest {
	public static void main(String[] args) {
		//System.out.println("主线程1");
		MyThread mt=new MyThread();
		mt.start();//启动线程
	}

}

1.2 实现Runnable接口创建线程

1.2.1 Runnable接口介绍

Runnable接口:

  • 只有一个方法run()。
  • Runnable是Java中用以实现线程的接口。
  • 任何实现线程功能的类都必须实现该接口。

为什么要实现Runnable接口?

  • Java不支持多继承。
  • 不打算重写Thread类的其他方法。

下面看一下示例代码:

package com.imooc.runnable;

class PrintRunnable implements Runnable {
	int i = 1;
	@Override
	public void run() {
		
		while (i <= 10)
			System.out.println(Thread.currentThread().getName() + "正在运行" + (i++));
	}

}

public class Test {

	public static void main(String[] args) {
		PrintRunnable pr = new PrintRunnable();
		Thread t1 = new Thread(pr);
		t1.start();
		//PrintRunnable pr1 = new PrintRunnable();
		Thread t2 = new Thread(pr);		// 两个线程共享了变量
		t2.start();

	}

}


2 线程的状态

2.1 线程的状态

下面看一下线程都具有哪些状态:

  • 新建(New)
  • 可运行(Runnable)
  • 正在运行(Running)
  • 阻塞(Blocked)
  • 终止(Dead)

如下为线程的状态转换图:
在这里插入图片描述

2.2 sleep方法

下面看一下sleep方法:
在这里插入图片描述
作用:在指定的毫秒数内让正在执行的线程休眠(暂停执行),参数为休眠的时间,单位是毫秒。

2.3 join方法

首先看下无参函数:

  • 作用是等待调用该方法的线程结束后才能执行,就是说某个线程调用的这个方法,那么其他线程必须等到这个方法执行完才能执行。
    在这里插入图片描述

下面看下带参的函数:

  • 等待该线程终止的最长时间为millis毫秒,如果millis为0则意味着要一直等下去。
    在这里插入图片描述

2.4 线程优先级

线程优先级简介:

  • Java为线程类提供了10个优先级。
  • 优先级可以用整数1-10表示,超过范围会抛出异常。
  • 主线程默认优先级为5。
  • 优先级常量:
    • MAX_PRIORITY:线程的最高优先级10
    • MIN_PRIORITY:线程的最低优先级1
    • NORM_PRIORITY:线程的默认优先级5

在这里插入图片描述


3 线程间同步

先来看下多线程运行问题:

  • 各个线程是通过竞争CPU时间而获得运行机会的
  • 各线程什么时候得到CPU时间,占用多久,是不可预测的
  • 一个正在运行着的线程在什么地方被暂停是不确定的

下面看下银行存取款问题:

  • 为了保证在存款或取款的时候,不允许其他线程对帐户余额进行操作
  • 需要将Bank对象进行锁定
  • 使用关键字synchronized实现

具体的代码就不贴了,下面看下synchronized关键字的使用,synchronized关键字用在:

  • 成员方法
  • 静态方法
  • 语句块
    在这里插入图片描述
    语句块时如下:
    在这里插入图片描述

4 线程间通信

先看下线程间通信可以使用的几个方法:

  • wait()方法:中断方法的执行,使线程等待。
  • notify()方法:唤醒处于等待的某一个线程,使其结束等待。
  • nofifyAll()方法:唤醒所有处于等待的线程,使它们结束等待。

下面以生产者消费者为例简单的演示下java中的线程间通信:

Queue.java:

package com.imooc.queue;

public class Queue {
	private int n;
	boolean flag=false;
	
	public synchronized int get() {
		if(!flag){
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("消费:"+n);
		flag=false;//消费完毕,容器中没有数据
		notifyAll();
		return n;
	}

	public synchronized void set(int n) {
		if(flag){
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("生产:"+n);
		this.n = n;
		flag=true;//生产完毕,容器中已经有数据
		notifyAll();
	}
	
}

Consumer.java:

package com.imooc.queue;

public class Consumer implements Runnable{
	Queue queue;
	Consumer(Queue queue){
		this.queue=queue;
	}

	@Override
	public void run() {
		while(true){
			queue.get();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
}

Producer.java:

package com.imooc.queue;

public class Producer implements Runnable{
	Queue queue;
	Producer(Queue queue){
		this.queue=queue;
	}

	@Override
	public void run() {
		int i=0;
		while(true){
			queue.set(i++);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}

}

Test.java:

package com.imooc.queue;

public class Test {

	public static void main(String[] args) {
		Queue queue=new Queue();
		new Thread(new Producer(queue)).start();
		new Thread(new Consumer(queue)).start();
	}

}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值