欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java多线程

程序员文章站 2022-03-08 22:37:28
...

什么是线程?

进程是指运行中的应用程序,每个进程都有自己独立的地址空间(内存空间),比如用户点击桌面的IE浏览器,就启动了一个进程,操作系统就会为该进程分配独立的地址空间。当用户再次点击左面的IE浏览器,又启动了一个进程,操作系统将为新的进程分配新的独立的地址空间。目前操作系统都支持多进程。

注意:用户每启动一个进程,操作系统就会为该进程分配一个独立的内存空间。请注意是独立的内存空间

线程的五种状态:

  1. 新建状态(new)

  2. 就绪状态(Runnable)

  3. 运行状态(Running)

  4. 阻塞状态(Blocked)

  5. 死亡状态(Dead)

Java多线程

创建线程的两种方式:

1、继承Thread类

Java提供了java.lang.Thread类支持多线程编程

public class MyThread extends Thread{
	public void run(){
		for (int i = 1; i < 10; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread thread = new MyThread();
		thread.start(); //调用start()方法启动线程
		thread.run();				
	}
}

Java多线程
注意:如果直接调用run()方法的话,则是使用主线程运行。
如果调用start()方法的话,则是一条单独的子线程。

2、实现Runnable接口:

  1. 实现run()方法;

  2. 编写线程执行体;

  3. 创建线程对象;

  4. 调用start()方法启动线程。

public class MyRunnable implements Runnable {

	//Runnable中包含run()方法,必须重写run()
	public void run() {
		// TODO Auto-generated method stub
		for (int i = 1; i < 10; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyRunnable runnable = new MyRunnable();
		MyRunnable runnable1 = new MyRunnable();
		
		Thread thread = new Thread(runnable);
		Thread thread1 = new Thread(runnable1);
		
		thread.start();
		thread1.start();
		
	}
}

这里使用两个对象调用start()方法,则是两条线程交替执行。

结果如下图:

Java多线程

Thread类和Runnable接口的区别:

一、继承Thread类
  编写简单,可直接操作线程
  适用于单继承
二、实现Runnable接口
  避免单继承局限性
  便于共享资源

主线程

main()方法即为主线程入口
产生其他子线程的线程
必须最后完成执行,因为它执行各种关闭动作

线程的休眠

在程序中允许一个线程进行暂时休眠,直接使用Thread.sleep()方法即可实现线程的休眠。

sleep()方法会让当前线程休眠(停止执行)millis毫秒,线程由运行中的状态进入不可运行状态,睡眠时间过后会再次进入可运行状态。

注意:调用sleep()方法需处理InterruptedException异常

public class Sleep implements Runnable {

	public void run() {
		for (int i = 0; i < 5; i++) {
			try {
				Thread.sleep(1000);  //睡眠一秒
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(i+1+"秒");
		}	
	}	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread td = new Thread(new Sleep());
		td.start();
	}
}

结果如下图所示:
Java多线程

线程的强制执行

join()方法使当前线程暂停执行,等待调用该方法的线程结束后再继续执行本线程。

注意:调用join()方法需处理InterruptedException异常

public class JoinDemo implements Runnable{

	public void run() {
		for (int i = 0; i <10; i++) {
			try {
				Thread.sleep(10); //增加线程交替执行的几率
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}  
			//输出当前线程的信息
			System.out.println(Thread.currentThread().getName()+"运行:"+i);
		}		
	}
	
	public static void main(String[] args) {
		//创建子线程并启动
		Thread td = new Thread(new JoinDemo());
		td.start();
		for (int i = 0; i < 20; i++) {
			if (i == 5) {
				try {
					td.join(); //阻塞主线程,子线程强制执行
				} catch (InterruptedException e) {
					e.printStackTrace();
				}			
			}
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"运行:"+i);
		}
	}
}

结果如下图所示:
Java多线程

线程的同步

当两个或多个线程需要访问同一资源时,需要以某种顺序来确保该资源某一时刻只能被一个线程使用,这就称为线程同步。

采用线程同步来控制线程的执行有两种方式,即同步代码方法和同步代码块。这两种方式均使用synchronized关键字来实现。

1、同步方法

public class Site implements Runnable{
	private int count = 10;  //剩余票数
	private int num = 0;   //买到第几张票
	private boolean flag = false;  //记录是否售完
	
	public void run() {
		// TODO Auto-generated method stub
		while(!flag){
		sale();
    }
  }
  //同步方法:售票
  public synchronized void sale(){
	  if (count <= 0) {
		flag = true;
		return;
	}
	  //第一步:修改数据
	  num++;
	  count--;
	  try {
		Thread.sleep(500); //模拟网络延迟
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} 
	  //第二步:显示信息
	  System.out.println(Thread.currentThread().getName()+"抢到第"+num+"张票,剩余"+count+"张票");
  }
}

2、同步代码块

public class Site implements Runnable{
	private int count = 10;  //剩余票数
	private int num = 0;   //买到第几张票
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			synchronized (this) {  //同步代码块
				//没有余票时,跳出循环
				if (count <= 0) {
					break;
				}
				//第一步:修改数据
				num++;
				count--;
				try{
					Thread.sleep(500);  //模拟网络延时
				}catch(InterruptedException e){
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"抢到第"+num+"张票,剩余"+count+"张票");
			}
		}
	}
}
相关标签: 多线程 java