JavaSE多线程(JavaSE大全)

本文介绍了Java中的多线程概念,包括进程与线程的区别,线程的创建与管理,如通过继承Thread类和实现Runnable接口的方式。还讨论了线程的常用方法如sleep()、currentThread()和setPriority(),以及join()方法、中断标志和线程同步。通过synchronized关键字实现的线程同步避免了数据竞争,但也可能导致死锁,文章提供了避免死锁的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一章节:JavaSE集合框架(JavaSE大全)
进程和线程
Java是少数的几种支持“多线程”的语言之一。大多数的程序只能循序运行单独一个程序块,但无法同时运行不同的多个程序块。
进程:
是程序的一次动态执行过程,它经历了从代码加载,执行到执行完毕的一个完整过程,这个过程也是进程本身从产生,发展到最终消亡的过程。多进程操作系统能同时运行多个进程(程序)。
CPU通过时间片切换来实现并发处理器。由于CPU执行速度非常快,使得所有程序好像在“同时”运行一样
线程
线程是CPU调度和分派的基本单位,他可与同属一个进程的其他的线程共享进程拥有的全部资源,多个线程共享内存,从而极大地提高了程序的运行效率。
一个或更多的线程构成一个进程(操作系统是以进程为单位,而进程是以线程为单位的,进程中必须有一个主线程main)。
进程和线程的关系:
进程的产生,很定会产生至少一个以上的线程;
进程关闭,该进程的线程会全部销毁;
线程销毁,进程未必会关闭

继承Thread实现多线程
多线程:指的是一个进程内的多个任务并发执行。
多线程的实现:
(1)继承Thread类,重写run()方法;
(2)实现Runnable接口,实现run()方法;

public class ThreadJiCheng {
	public static void main(String[] args) {
		//创建线程对象
		MyThread mThread=new MyThread();
		MyThread mThread1=new MyThread();
		MyThread mThread2=new MyThread();
		MyThread mThread3=new MyThread();
		MyThread mThread4=new MyThread();
		//启动线程
		mThread.start();
		mThread1.start();
		mThread2.start();
		mThread3.start();
		mThread4.start();
	}
}

class MyThread extends Thread{
	//run方法既没有参数也没有返回值
	public void run() {
		System.out.println("执行了线程的run()方法");
		try {
			Thread.sleep(2000);//休眠
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Runnable接口实现多线程

public class RunnableShiXian {
	public static void main(String[] args) {
		MyRunnable mRunnable=new MyRunnable("1线程");
		MyRunnable mRunnable1=new MyRunnable("1线程");
		MyRunnable mRunnable2=new MyRunnable("1线程");
		MyRunnable mRunnable3=new MyRunnable("1线程");
		Thread t1=new Thread(mRunnable);
		Thread t2=new Thread(mRunnable1);
		Thread t3=new Thread(mRunnable2);
		Thread t4=new Thread(mRunnable3);
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

class MyRunnable implements Runnable{
	String name;
	public MyRunnable(String name) {
		super();
		this.name = name;
	}
	@Override
	public void run() {
		System.out.println("线程run()方法执行了:"+this.name);
		try {
			for (int i = 0; i < 5; i++) {
				System.out.println("执行了");
			}
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
}

Thread常用方法
(1)Thread.sleep(毫秒数)阻塞的方法
让线程休眠,时间到,自动唤醒并继续执行
(2)Thread.currentThread()
表示获取当前正在执行的线程对象
(3)setPriority(int i)
给线程设置优先级,范围是1-10,这里优先级高,并不代表一定先执行,只是增加抢占到资源的机会.

package com.zx.DuoXianCheng;

public class ThreadChangYongFangFa {
	public static void main(String[] args)throws Exception {
		MyThread1 myThread1=new MyThread1("1");
		MyThread1 m2=new MyThread1("2");
		MyThread1 m3=new MyThread1("3");
		MyThread1 m4=new MyThread1("4");
		
		myThread1.setPriority(1);
		m4.setPriority(4);
		m3.setPriority(2);
		m2.setPriority(3);
		
		myThread1.start();
		m2.start();
		m3.start();
		m4.start();
		
		
		/*int i=0;
		while(1==1) {
			System.out.println("计时器:"+i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			i++;
		}*/
	}
}


class MyThread1 extends Thread{
	String name;
	public MyThread1(String name) {
		super();
		this.name = name;
	}
	//run方法既没有参数也没有返回值
	public void run() {
		System.out.println("执行了线程:"+this.name+"中的run方法");
	//	System.out.println("执行了线程的run()方法"+Thread.currentThread().getName());
	//	System.out.println("当前执行的线程对象:"+Thread.currentThread().getName());
		}
}

join()方法
Join()方法:
当前线程暂停执行,新加入的线程开始执行,当新线程执行完之后,在执行当前线程。

package com.zx.DuoXianCheng;

public class JoinFangFa {
	public static void main(String[] args) throws InterruptedException {
		MyThread2 m1=new MyThread2("1");
		MyThread2 m2=new MyThread2("2");
		MyThread2 m3=new MyThread2("3");
		m1.start();
		m2.start();
		m3.start();
		
		m1.join();
		m2.join();
		m3.join();
		System.out.println("程序结束");
	}
	
	
}

class MyThread2 extends Thread{
	String name;

	public MyThread2(String name) {
		this.name = name;
	}
	public void run() {
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("线程"+this.name+"结束");
	}
	
}

线程终止
Interrupt()设置线程中断标志,默认值为False
(无法打断该线程的执行,但是可以获得该线程中被中断的标志,interrupt()得到true,判断中断)标志决定是否要终止线程

package com.zx.DuoXianCheng;

public class XianChengZhongZhi {
	public static void main(String[] args) throws InterruptedException {
		myThread3 m1=new myThread3("1");
		System.out.println("设置终止前:"+m1.isInterrupted());
		m1.start();
		//2秒后将子线程的中断标志设置为true
		Thread.sleep(100);
		m1.interrupt();
		System.out.println("设置终止后:"+m1.isInterrupted());
	}
}

class myThread3 extends Thread{
	String name;
	public myThread3(String name) {
		this.name = name;
	}
	public void run() {
		System.out.println("线程"+this.name+"开始执行");
		int i=0;
		while(1==1) {
			if (Thread.currentThread().isInterrupted()==false) {
				System.out.println("继续执行"+i);
				i++;
			}
		}
	}
}

线程同步
Java中引用对象互斥锁概念,保证共享数据操作的完整性,每个对象都对应于一个可称为“互斥锁”的标记,这个标记在任一时刻,只能有一个线程访问对象
关键字:synchronized给对象加互斥锁。
两种实现方式:
(1)给代码块加锁(锁定某个对象)
Synchronized(obj){执行内容}
(2)给方法加锁(锁定方法实现的过程)
Public synchronized void method(){…方法体…}

demo:两人取钱问题

package com.zx.DuoXianCheng;

public class XianChengTongBu {
	public static void main(String[] args) {
		myThread6 m1=new myThread6("1");
		myThread6 m2=new myThread6("2");
		m1.start();
		m2.start();
	}
	
}

class Bank{
	String account;
	double banlance;
	public Bank(String account, double banlance) {
		this.account = account;
		this.banlance = banlance;
	}
	//取款()不加同步
	public void drawAccount(String name) throws InterruptedException {
		this.banlance=this.banlance-200;
		Thread.sleep(100);
		System.out.println(name+"取款后账户余额为:"+this.banlance);
	}
	//取款()同步代码
	public void drawAccount1(String name) throws InterruptedException {
		synchronized (this) {//锁定某个对象
			this.banlance=this.banlance-200;
			Thread.sleep(100);
			System.out.println(name+"取款后账户余额为:"+this.banlance);
		
		}
	}
		//取款()同步方法
		public synchronized void drawAccount2(String name) throws InterruptedException {
				this.banlance=this.banlance-200;
				Thread.sleep(100);
				System.out.println(name+"取款后账户余额为:"+this.banlance);
			
	}
	
}

class myThread6 extends Thread{
	String name;
	
	static Bank bank=new Bank("1", 1000);
	public myThread6(String name) {
		this.name = name;
	}
	public void run() {
		while(1==1) {
			if (bank.banlance>=200) {
				try {
					bank.drawAccount2(this.name);
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}else {
					System.out.println("钱没了");
					return;
				}
			}
	}
}

线程死锁:
不同的线程都在等待不可能被释放的锁,多个线程同时被阻塞,因此所有的工作都无法完成。
在使用“synchronized”关键词时,很容易出现两个线程互相等待对方做出某个动作而出现死锁的情形。
避免死锁的技巧
当几个线程都要访问共享资源A,B,C时,保证使每个线程都按照同样的顺去去访问他们,例如全都先访问a,再访问b,最后访问c。

public static void main(String[] args) throws InterruptedException {
		MyThread10 mt=new MyThread10("线程一");
		MyThread10 mt1=new MyThread10("线程二");
		mt.start();
		Thread.sleep(100);
		mt1.start();
	}
}

class MyThread10 extends Thread{
	static Object a=new Object();
	static Object b=new Object();
	String name;
	public MyThread10(String name) {
		this.name = name;
	}
	
	public void run(){
		if ("线程一".equals(this.name)) {
			synchronized(a) {
				System.out.println(this.name+"锁定资源a");
				try {
					Thread.sleep(108);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized(b) {
					System.out.println(this.name+"锁定");
				}
			}
		}if ("线程二".equals(this.name) ){
			synchronized(b) {
				System.out.println(this.name+"锁定资源b");
				try {
					Thread.sleep(108);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized(a) {
					System.out.println(this.name+"锁定资源a");
				}
			}
		}
	}
	
}

下一章节:JavaSE I/O流(JavaSE大全)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值