Java线程篇---两种构建线程的方法

本文详细介绍了Java中的线程概念,包括线程的创建、同步机制,如synchronized和ReentrantLock,并展示了线程安全问题的解决方案。此外,还探讨了Java定时器的使用,通过TimerTask实现周期性任务。内容涵盖线程的生命周期、线程同步、线程安全的实现方法以及定时任务的创建和取消。
摘要由CSDN通过智能技术生成

基础知识

  1. 线程
    线程是操作系统能够进行运算调度的最小单位,被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务
  2. 线程锁
    锁定一个公共的变量在一个线程中,其它未取得的线程处于等待中,一直等到变量被线程锁释放,避免多个线程同时使用一个变量造成数据错误
  3. 多线程存在的机制
    真正的同步执行几个线程是不存在的,由于CPU的处理速度极快,所以每个一定的时间处理一个线程的一部分,在人看起来就像是并行,而线程与线程之间是通过竞争来实现执行的,可以通过设置优先级来控制线程得到执行的机会

一、继承Thread来创建线程类

① 函数
函数作用函数名解释
获取当前线程Thread.currentThread()返回当前线程
获取线程名getName()获取线程名
设置线程名setName(name)设置线程名
设置守护线程setDaemon(true/false)被设置守护的线程会随主线程的结束而销毁
启动线程start()触发线程
加入其他线程join()加入的线程会优先执行完再执行主线程
线程休眠Thread.sleep(time)暂停当前线程time时间
获取线程优先级getPriority()获取线程优先级
设置线程优先级setPriority()设置线程优先级(优先级在1到10的数字)
获取线程组getThreadGroup()获取线程组
线程中断interrupt()设置线程的中断标志,需在run()中处理
线程中断interrupted()线程是否中断
线程中断isInterrupted()线程是否中断
② 实例
public class MyThread extends Thread{//继承Thread类
 	//重写run()方法
 	public void run() {
		for(int i = 0; i < 100; i++) {
 			if(interrupted()) {
 				break;//手动设置终止线程的操作
 			}
 			System.out.println("线程名" + getName() + ": " + i);
 		}
 		System.out.println("线程操作方法");
 	}
 	//测试
 	public static void main(String[] args) {
 		MyThread thread = new MyThread();
 		
 		thread.setName("线程");//修改线程名
 		System.out.println(thread.getName());//获得线程名
 		
 		System.out.println(thread.getPriority());//获得线程优先级
 		System.out.println(Thread.MAX_PRIORITY);//最大优先级
 		System.out.println(Thread.MIN_PRIORITY);//最小优先级
 		System.out.println(Thread.NORM_PRIORITY);//正常优先级
 		thread.setPriority(5);//设置优先级
 		
 		thread.start();//开启线程
 		
 		ThreadGroup thgroup = thread.getThreadGroup();//得到该线程的线程组,线程组的作用是可以批量操作线程
 		Thread th = new Thread(thgroup, "线程");//创建特定线程组的线程
 		
 		thread.setDaemon(true);//设置thread为守护线程
 		
 		thread.interrupt();//终止线程,需要在run()方法里进行相应处理,否则不会终止线程
		
 		try {
 			thread.join();//将线程加入到主线程中,然后先将该线程处理结束后,在处理主线程
 		} catch (InterruptedException e) {
 			e.printStackTrace();
 		}
 		
 		Thread mainThread = Thread.currentThread();//获得当前程序的线程
		
 		try {
 			Thread.sleep(1000);//设置当前线程休眠1秒
 		} catch (InterruptedException e) {
 			e.printStackTrace();
 		}
 	}
 }
  1. 优点:创建线程对象简单
  2. 缺点:创建线程间的数据共享只能通过静态变量来实现

二、实现Runnable接口来创建线程类

class MyRunnable implements Runnable{

	public void run() {
		for(int i = 0; i < 100; i++) {
			 System.out.println("线程名" + Thread.currentThread().getName() + ": " + i);
		}
	}

	public static void main(String[] args) {
		MyRunnable myRunnable = new MyRunnable();
		
		Thread thread = new Thread(myRunnable,"线程");//创建线程
		thread.start();//运行线程,其他操作等同于上面操作,此处省略
	}
}
  1. 优点:实现的Runnable接口的类中定义的变量可以被所有线程共享
  2. 缺点:创建线程得通过Thread()来实现

三、三种解决线程安全的方法

  1. 第一种方法 —>同步锁synchronized (Object lock)
class MyRunnable implements Runnable{
	private int ticketNum = 100;
	private Object lock = new Object();//线程共有的同步锁对象
	//第一种方法
	public void run() {
		while(true) {
			synchronized (lock) {//同步锁,必须给定一个所有线程共有的变量对象
				if(ticketNum > 0) {
					System.out.println(Thread.currentThread().getName() + "卖出第" + ticketNum + "张票");
					ticketNum--;
				}
				else {
					break;
				}
			}
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
  1. 第二种方法 —>同步方法
class MyRunnable implements Runnable{
	private int ticketNum = 100;
	public void run() {
		while(ticketNum > 0) {
			saleTicket();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	private synchronized void saleTicket() {//在函数返回值前加入synchronized构成同步方法
		if(ticketNum > 0) {
			System.out.println(Thread.currentThread().getName() + "卖出第" + ticketNum + "张票");
			ticketNum--;
		}
	}
}
  1. 第三种方法 —>ReentrantLock
class MyRunnable implements Runnable{
	private int ticketNum = 100;
	private ReentrantLock lock1 = new ReentrantLock();//线程共有的锁对象
	public void run() {
		while(true) {
			lock1.lock();//上锁
			if(ticketNum > 0) {
				System.out.println(Thread.currentThread().getName() + "卖出第" + ticketNum + "张票");
				ticketNum--;
			}
			else {
				break;
			}
			lock1.unlock();//解锁
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

四、定时器的使用------重写TimerTask中的run()方法

class MyTimerTask extends TimerTask{

	public void run() {
		System.out.println("定时器");
	}
	
	public static void main(String[] args) {
		Timer time = new Timer();
		
		time.schedule(new MyTimerTask(), 2000,500);//延迟2s启动计时器,然后以每0.5s启动一次
		time.cancel();//关闭计时器
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值