一、线程概念
异步和同步:
就像我们每天去到公司一样,先打开电脑,在电脑开机过程中可以去接点水喝,而不用等待电脑开机再去接水喝。
并发和并行:
二、线程的优势
现如今服务器多采用多处理器,CPU的基本调度单位是线程,如果一个程序只有一个线程的话,那么就只能发挥一个CPU的作用,其他CPU的资源将会闲置,这在很大程度上浪费了CPU的资源,如果能够多个CPU同时发挥作用,在设计正确的情况下,可以通过提高CPU资源的利用率来提高系统的吞吐率。
三、线程状态
通过Thread.state 可以查看线程的状态:

t.start()之后并不代表线程已经启动,此时它只是在可运行池中,随时等待被CPU调度,一旦获取到CPU时间片才真正的处于可运行状态。
线程的优先级:
1、线程有1-10,10个优先级选择,最小优先级是1(MIN_PRIORITY),默认优先级5(NORM_PRIORITY),
最大优先级是10(MAX_PRIORITY)
/**
* The minimum priority that a thread can have.
*/
public final static int MIN_PRIORITY = 1;
/**
* The default priority that is assigned to a thread.
*/
public final static int NORM_PRIORITY = 5;
/**
* The maximum priority that a thread can have.
*/
public final static int MAX_PRIORITY = 10;2、如果没有指定线程的优先级,默认是普通优先级,也就是NORM_PRIORITY
3、通过t.setPriority(int newPriority)为线程设定优先级
注意:不要试图通过设定优先级来指定线程的启动顺序,优先级的设定只是说明这个线程在CPU调度时有更大的概率被选中,而且这种优先级设定有不确定性,在某些操作系统中可能优先级的设定并不起作用。
方法介绍:
sleep()和wait()的区别:
1、sleep()是Thread的静态方法,wait()是Object的方法。
2、当调用sleep()的线程获得锁时不会自动释放锁,调用wait()会释放锁。
3、sleep()方法需要其他线程调用当前线程的interrupt()方法或者时间过期才能唤醒,wait()方法需要调用t.notify()或者t.notifyAll()方法唤醒。
线程的中断:
如果线程执行完成或者抛出未处理的异常,线程就会终止。
线程中断的方法有stop()、resume()、suspend()和interrupt(),但是前三个已经废弃了,stop()会使线程不正确释放资源,resume()只是为了suspend()而存在,这两个方法会导致死锁。所以最后只剩下interrupt()了。
java线程是协作式的,意思就是当调用当前线程t的interrupt()时,当前线程t并不会立马终止,而是跟当前线程打个招呼,“兄弟,你死期到了,我跟你说一下,你爱死不死”,同时会把t的中断标志设置为true。当线程抛出InterruptedException时,线程中断标志将会清除,调用静态方法Thread.interrupted()可以判断线程是否中断,同时将中断标志将被清除并设置为false。
实例如下:
主函数
public static void main(String[] args) throws InterruptedException {
//创建两个线程
InterruptThread interruptThread = new InterruptThread();
interruptThread.setName("thread1");
InterruptThread2 interruptThread2 = new InterruptThread2();
interruptThread2.setName("thread2");
//启动两个线程
interruptThread.start();
interruptThread2.start();
//主线程休眠5秒 使两个线程充分运行
TimeUnit.SECONDS.sleep(5);
//中断InterruptThread
interruptThread.interrupt();
}静态内部线程1:
private static class InterruptThread extends Thread{
@Override
public void run() {
interrupt(); //将中断标志设置为true
System.err.println("before thread1 interrupt status:"+isInterrupted());
while (true){
try {
sleep(6000);
} catch (InterruptedException e) {
System.err.println("exception thread1 interrupt status:"+isInterrupted());
}
}
}
}静态内部线程2:
private static class InterruptThread2 extends Thread{
@Override
public void run() {
long start = System.currentTimeMillis();
while (true){
if (System.currentTimeMillis() - start > 2000){
interrupt(); //将中断标志设置为true
System.out.println("before thread2 interrupt status:"+isInterrupted());
break;
}
}
Thread.interrupted(); //清除中断标志,置为false
System.out.println("after thread2 interrupt status:"+isInterrupted());
}
}1、在InterruptThread 中先把中断标志设置为true,并打印是否中断,在主线程中再次将处于休眠状态中的InterruptThread 再次中断,此时会抛出异常,再次打印是否中断。在这个类中我们要证明的是,抛出InterruptedException 线程中断标志会被清除。
2、在InterruptThread2 中我们让InterruptThread2 正常运行2s,并在循环中将中断标志置为true,正常退出循环时,调用Thread.interrupted(); 清除中断标志,并打印是否中断。在这个类中我们要证明调用当前线程Thread.interrupted();会将中断标志清除。
在这两个类中证明了,java线程中断是协作式的,将中断标志置为true并不会立马就中断线程。
打印结果:
before thread1 interrupt status:true
exception thread1 interrupt status:false
before thread2 interrupt status:true
after thread2 interrupt status:false
exception thread1 interrupt status:false四、创建线程
创建线程有三种方法:
public class CreateThread {
public static void main(String[] args) {
ExtendThread extendThread = new ExtendThread();
extendThread.start();
}
private static class ExtendThread extends Thread{
@Override
public void run() {
System.out.println("class extends thread start");
}
}
}public class CreateThread {
public static void main(String[] args) {
Thread thread = new Thread(new ImplRunnable());
thread.start();
}
private static class ImplRunnable implements Runnable{
@Override
public void run() {
System.out.println("class implements Runnable start");
}
}
}Callable是可以获取到返回值, 但是只能通过线程池来调用,它返回的是一个Future对象f,通过f.get()就能获取到结果。
public class CreateThread {
private static ExecutorService executorService = Executors.newFixedThreadPool(4);
public static void main(String[] args) {
Future<String> submit = executorService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "success";
}
});
try {
String s = submit.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}能力一般,水平有限,如有错误,请多指出。