多线程相关(1)


线程是cpu任务调度的最小执行单位,每个线程拥有自己独立的程序计数器、虚拟机栈、本地方法栈。

线程状态:

线程状态包括:创建、就绪、运行、阻塞、死亡。
线程调度

状态切换

方法作用区别
start启动线程,由虚拟机自动调度执行run()方法线程处于就绪状态
run线程逻辑代码块处理,JVM调度执行线程处于运行状态
sleep让当前正在执行的线程休眠(暂停执行)不释放锁
wait使得当前线程等待释放同步锁
notify唤醒在此对象监视器上等待的单个线程唤醒单个线程
notifyAll唤醒在此对象监视器上等待的所有线程唤醒多个线程
yield停止当前线程,让同等优先权的线程运行用Thread类调用
join使当前线程停下来等待,直至另一个调用join方法的线程终止用线程对象调用

线程状态切换:
线程状态切换

阻塞与唤醒

阻塞

这三个方法的调用都会使当前线程阻塞。该线程将会被放置到对该Object的请求等待队列中,然后让出当前对Object所拥有的所有的同步请求。线程会一直暂停所有线程调度,直到下面其中一种情况发生:
其他线程调用了该 Object 的 notify 方法,而该线程刚好是那个被唤醒的线程;
其他线程调用了该 Object 的 notifyAll 方法。

唤醒

线程将会从等待队列中移除,重新成为可调度线程
它会与其他线程以常规的方式竞争对象同步请求。
一旦它重新获得对象的同步请求,所有之前的请求状态都会恢复,也就是线程调用 wait 的地方的状态。
线程将会在之前调用 wait 的地方*继续运行下去。

由于 wait() 属于 Object 方法,调用之后会强制释放当前对象锁,所以在 wait() 调用时必须拿到当前对象的监视器 monitor 对象。因此,wait() 方法在同步方法/代码块中调用

wait 与 sleep

  • wait 方法必须在 synchronized 保护的代码中使用,而 sleep 方法并没有这个要求。
  • wait 方法会主动释放 monitor 锁,在同步代码中执行 sleep 方法时,并不会释放 monitor 锁。
  • wait 方法意味着永久等待,直到被中断或被唤醒才能恢复,不会主动恢复,sleep 方法中会定义一个时间,时间到期后会主动恢复。
  • wait/notify 是 Object 类的方法,而 sleep 是 Thread 类的方法。

创建线程方式

1.实现 Runnable 接口(优先使用)

public class RunnableThread implements Runnable {    
	@Override    
	public void run() {
		System.out.println("实现Runnable接口,实现线程");
	}
}

2.实现Callable接口(有返回值可抛出异常)

class CallableTask implements Callable<Integer> {
	@Override    
	public Integer call() throws Exception { 
		return new Random().nextInt();
	}
}

3.继承Thread类(java不支持多继承)

public class ExtendsThread extends Thread {    
	@Override    
	public void run() {
		System.out.println("用Thread类实现线程");
	}
}

4.使用线程池(底层都是实现run方法)

static class DefaultThreadFactory implements ThreadFactory {    
	DefaultThreadFactory() {        
		SecurityManager s = System.getSecurityManager();        
		group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();        
		namePrefix = "pool-" + poolNumber.getAndIncrement() +"-thread-";    
	}    
	public Thread newThread(Runnable r) {        
		Thread t = new Thread(group, r,namePrefix + threadNumber.getAndIncrement(),0);        
		if (t.isDaemon()) 
			t.setDaemon(false);  //是否守护线程        
		if (t.getPriority() != Thread.NORM_PRIORITY) 
			t.setPriority(Thread.NORM_PRIORITY); //线程优先级        
		return t;    
	}
}

原文:https://mp.weixin.qq.com/s/IVgGXQKU1QiT1ToN2wXHJg

  • 22
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值