并发编程专题一-线程相关基础概念

原创
2019/04/14 12:21
阅读数 327

一、基础概念

1、CPU核心数和线程数的关系

核心数:线程数=1:1  ;使用了超线程技术后---> 1:2

2、CPU时间片轮转机制

又称RR调度,会导致上下文切换

3、什么是进程和线程

进程:程序运行资源分配的最小单位,进程内部有多个线程,会共享这个进程的资源

线程:CPU调度的最小单位,必须依赖进程而存在。

4、澄清并行和并发

并行:同一时刻,可以同时处理事情的能力

并发:与单位时间相关,在单位时间内可以处理事情的能力

5、高并发编程的意义、好处和注意事项

好处:充分利用cpu的资源、加快用户响应的时间,程序模块化,异步化

存在问题:

线程共享资源,存在冲突;

容易导致死锁;

启用太多的线程,就有搞垮机器的可能

二、认识Java里的线程

1、新启线程的方式

三种实现方式

继承类Thread

实现接口Runnable

实现 接口 Callable
 
代码如下
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * @Auther: BlackKingW
 * @Date: 2019/4/14 12:09
 * @Description:
 */
public class NewThread {
	/*继承自Thread类*/

	private static class UseThread extends Thread{
		@Override
		public void run() {
			System.out.println("I am extends Thread");

		}
	}
	/*实现Runnable接口*/
	private static class UseRun implements Runnable{

		@Override
		public void run() {
			System.out.println("I am implements Runnable");
		}
		
	}
	
	/*实现Callable接口,允许有返回值*/
	private static class UseCall implements Callable<String>{

		@Override
		public String call() throws Exception {
			System.out.println("I am implements Callable");
			return "CallResult";
		}
		
	}


	public static void main(String[] args) 
			throws InterruptedException, ExecutionException {
		UseThread useThread = new UseThread();
		useThread.start();

		
		UseRun useRun = new UseRun();
		new Thread(useRun).start();
		Thread t = new Thread(useRun);
		t.interrupt();
		
		UseCall useCall = new UseCall();
		FutureTask<String> futureTask = new FutureTask<>(useCall);
		new Thread(futureTask).start();
		System.out.println(futureTask.get());
	}
}
需要注意的是,实现Callable是不能直接放在线程里使用的,必须使用FutureTask包装之后才能在线程里使用。如果想要获取Callable执行结果的返回值,则需要借助FutureTask 的get方法。

2、线程安全的停止

1、线程自然终止:自然执行完或抛出未处理异常

2、stop(),resume(),suspend()已不建议使用,stop()会导致线程不会正确释放资源,suspend()容易导致死锁。

3、使用interrupt()方法

java线程是协作式,而非抢占式

调用一个线程的interrupt() 方法中断一个线程,并不是强行关闭这个线程,只是跟这个线程打个招呼,将线程的中断标志位置为true,线程是否中断,由线程本身决定。

isInterrupted() 判定当前线程是否处于中断状态。

static方法interrupted() 判定当前线程是否处于中断状态,同时中断标志位改为false。

方法里如果抛出InterruptedException,线程的中断标志位会被复位成false,如果确实是需要中断线程,要求我们自己在catch语句块里再次调用interrupt()。

代码如下


import java.util.concurrent.ExecutionException;

/**
 * @Auther: BlackKingW
 * @Date: 2019/4/14 12:09
 * @Description:
 */
public class DaemonThread {


	private static class UseThread extends Thread {
		@Override
		public void run() {
			try {
				while (!isInterrupted()) {
					System.out.println(Thread.currentThread().getName()
							+ " I am extends Thread.");
				}
				System.out.println(Thread.currentThread().getName() 
						+ " interrupt flag is " + isInterrupted());
			} finally {
				System.out.println("...........finally");
			}
		}
	}

	public static void main(String[] args) throws InterruptedException, 
		ExecutionException {
		UseThread useThread = new UseThread();
		useThread.start();
		Thread.sleep(5);
		useThread.interrupt();
	}
}

3、线程的状态

线程常用方法和线程的状态

线程只有5种状态。整个生命周期就是这几种状态的切换。

run()和start() :run方法就是普通对象的普通方法,只有调用了start()后,Java才会将线程对象和操作系统中实际的线程进行映射,再来执行run方法。

yield() :让出cpu的执行权,将线程从运行转到可运行状态,但是下个时间片,该线程依然有可能被再次选中运行。

线程的优先级

取值为1~10,缺省为5,但线程的优先级不可靠,不建议作为线程开发时候的手段

守护线程

和主线程共死,finally不能保证一定执行,可以使用

Thread.setDaemon(true);

方法将线程设置为守护线程。

展开阅读全文
加载中

作者的其它热门文章

打赏
1
2 收藏
分享
打赏
0 评论
2 收藏
1
分享
返回顶部
顶部