java多线程

本文详细介绍了Java中的多线程概念,包括进程与线程的区别,线程的创建(通过继承Thread、实现Runnable接口和Callable接口),线程的状态及其转换,以及线程的常用方法。同时,讨论了线程同步和死锁问题,强调了synchronized关键字在确保线程安全中的作用。此外,提到了Java中线程的调度方式和线程的优先级。
摘要由CSDN通过智能技术生成

多线程

进程:一个应用程序或软件
线程:一个进程的执行场景或执行单元
一个进程可以启动多个线程
注意:

  1. 进程A和进程B的内存独立不共享
  2. 在Java中:线程A和线程B,堆内存和方法区内存共享,但是栈内存独立,一个线程一个栈,每个栈之间互不干扰,各自执行,这就是多线程并发。

创建进程方法:

  1. 创建一个类继承Thread重写run()方法
public class Thread {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		MyThread mt=new MyThread();
		mt.start();//开启一个线程,立马结束,这并不是并发
	}

}
class MyThread extends Thread {//编写一个类直接继承Thread
	 
	 public void run() {//重写run方法
		//这段程序运行在分支线程中
		for(int i=0;i<100;i++) {
			System.out.println("分支线程->"+i);
		}
	}

}
  1. 实现Runnable接口
public class Thread {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Thread t=new Thread(new MyThread());
		t.start();//开启一个线程,立马结束,这并不是并发
	}           

}
class MyThread implements Runnable {

	@Override
	public void run() {
		// TODO 自动生成的方法存根
		for(int i=0;i<10;i++) {
			System.out.println("分支线程->"+i);
		}
	}
}

3.实现Callable接口,可以获取线程的返回值,前面的是无法获取的,但是效率比较低。

public static void main(String[] args) {
		// TODO 自动生成的方法存根
		FutureTask ft=new FutureTask(new Callable() {
			@Override
			public Object call() throws Exception {
				// TODO 自动生成的方法存根
				System.out.println("123");
				return 1;
			}
		});
		Thread t=new Thread(ft);
		t.start();
		Object a=null;
		try {
			a = ft.get();//获取返回值
		} catch (InterruptedException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		System.out.println(a);
	}

线程方法

  1. start():启动一个分支线程,只为开启一个线程空间,开启空间后会立马结束,启动成功的线程会自动调用run方法
  2. setName(String ):获取线程名字
  3. String getName():获取线程名字
  4. static Thread currentThread():获取当前线程,这段代码出现在哪里,线程就是那个,这个方法是静态方法
  5. static sleep(long millis):让当前线程进入休眠,进入阻塞状态,放弃cpu时间片,让给其他线程使用,参数是毫秒,需要异常处理
  6. intrrupt():叫醒线程,用的是异常处理机制
  7. stop():终止线程,已过时
  8. int getpriority():获取线程优先级(1~10)最低是1,默认是5
  9. void setPriority(int ):设置优先级
  10. static void yeild():让位方法,暂停当前正在执行的线程,并执行其他线程,它不是阻塞,会让当前线程运行状态变成就绪状态。回到就绪还可能再抢到
  11. void join():合并线程
t.join()//当前线程阻塞,t线程执行,t线程结束,才运行。
  1. setDaemon(boolean ):设置守护线程。

线程生命周期
调用start方法会出现就绪状态,run方法的开始执行标志着进入运行状态,当之前占有的时间片用完过后,会重新回到就绪状态继续抢夺时间片,抢夺到时间片后,会重新进入run方法接着上次代码继续执行下去。run方法执行结束标志进入死亡状态。

新建状态:刚new出来的对象
就绪状态:也叫可以运行状态,表示当前线程可以抢夺cup时间片的权力,当抢夺到一个cpu时间片后,开始执行run方法。
运行状态:run方法执行
阻塞状态:当一个线程出现阻塞事件,例如接收用户键盘输入、sleep方法,此时线程会进入阻塞状态,阻塞状态的线程会放弃之前占有的时间片。是由运行状态转变过来的,阻塞状态结束会回到就绪状态。
死亡状态:run方法执行结束

线程的调度
抢占式:那个线程的优先级比较高哪个就抢到的概率高一些(Java使用)
均分式:平均分配cpu时间片

线程安全
线程同步:线程排队执行,不能并发,会牺牲效率,用于解决线程安全问题。

同步编程:线程t1在执行之前必须等待t2执行结束,两线程之间发生了排队关系0
异步编程:线程t1和线程t2,各自执行各的,互不相干

synchronized
线程同步代码块
将要是共享的代码放入即可

synchronized(){//括号里面的参数是共享对象,也就是需要排队的对象
}

锁池:当运行有sychronized的代码时,需要去找锁(每个Java对象都有一把锁),从运行状态变为就绪状态,找不到等待,找到了,抢时间片再运行。

synchronized出现在静态方法上,是以类为对象的
synchronized出现在实例方法上是以this为对象

局部变量:在栈中
实例变量:在堆中
静态变量:在方法区
局部变量不会有线程安全问题

死锁

public class Thread_tset {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Object o1=new Object();
		Object o2=new Object();
		Thread t1=new MyThread1(o1,o2);
		Thread t2=new MyThread2(o1,o2);
	}
}
class MyThread1 extends Thread{
	Object o1;
	Object o2;
		public  MyThread1() {
		
	}
		public  MyThread1(Object o1,Object o2) {
			this.o1=o1;
			this.o2=o2;
		}
		public void run() {
			synchronized(o1){
			try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}
				synchronized(o2) {
					
				}
			}
		}
}
class MyThread2 extends Thread{
	Object o1;
	Object o2;
		public  MyThread2() {
		
	}
		public  MyThread2(Object o1,Object o2) {
			this.o1=o1;
			this.o2=o2;
		}
		public void run() {
			synchronized(o2){
			try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}
				synchronized(o1) {
					
				}
			}
		}
}

用户线程(后台线程):main线程
守护线程:一般守护线程是一个死循环,所有的用户线程只要结束,守护线程自动结束
例如,垃圾回收线程

定时器
间隔特定的时间,执行特定的程序
可以使用类库:java.util.Timer
现在使用较多的是SwingTask框架

Object的wait和notify方法
不是线程的方法
wait():

Object o=new Object();
o.wait();//让正在O对象上活动的线程进入等待状态,无期限等待,直到被唤醒,会使线程释放之前的锁

notify():

o.notify();//可以让正在o对象上等待的线程唤醒,只会通知不会释放锁。

notifyAll():唤醒所有正在o对象上等待的线程
waith和notify方法都必须建立在线程同步的基础上,因为必须保证数据安全问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值