首页 > 代码库 > (CZ深入浅出Java基础)线程笔记
(CZ深入浅出Java基础)线程笔记
一.线程的引入
1.多线程概述
1.1.进程
a.正在运行的程序,是系统进行资源分类和调用的独立单位。
b.每个进程都有它自己的内存空间和系统资源。
1.2.线程
a.是进程中的单个顺序控制流,是一条执行路径。
b.一个进程如果只有一条路径,则称为单线程程序。
c.一个进程如果有多条执行路径,则称为多线程程序。
1.3.小结
线程多的进程抢到CPU执行权的概率大,但是仍具有随机性。
2.Java程序运行原理
2.1.Java运行
Java命令会启动Java虚拟机,启动JVM,等于启动了一个应用程序,也就是启动了一个进程。该进程会自动启动一个“主线程”,然后主线程去调用某个类的main方法。
3.并发和并行
3.1.并发
物理上的同时发生,并发是在同一个时间点上同时发生。
3.2.并行
逻辑上的同时发生,并行是在同一个时间段上同时发生。
二.线程的使用
1.多线程的使用举例
1 public class Demo { 2 3 public static void main(String[] args) { 4 // TODO Auto-generated method stub 5 MyThread my1=new MyThread(); 6 MyThread my2=new MyThread(); 7 my1.start(); 8 my2.start(); 9 } 10 11 } 12 13 class MyThread extends Thread{ 14 @Override 15 public void run() { 16 // TODO Auto-generated method stub 17 for(int i=0;i<1000;i++){ 18 System.out.println(i); 19 } 20 } 21 }
2.线程的基本使用
2.1.获取名称
1 public class Demo { 2 3 public static void main(String[] args) { 4 // TODO Auto-generated method stub 5 MyThread my1 = new MyThread(); 6 MyThread my2 = new MyThread(); 7 my1.start(); 8 my2.start(); 9 } 10 11 } 12 13 class MyThread extends Thread { 14 @Override 15 public void run() { 16 // TODO Auto-generated method stub 17 for (int i = 0; i < 1000; i++) { 18 System.out.println(getName() + ":" + i); 19 } 20 } 21 }
获取当前进程对象:
public class Demo { public static void main(String[] args) { // TODO Auto-generated method stub Thread main_thread = Thread.currentThread(); System.out.println(main_thread.getName()); } }
2.2.设置线程名称
可以通过构造函数,也可以通过setName方法
1 public class Demo { 2 3 public static void main(String[] args) { 4 // TODO Auto-generated method stub 5 // MyThread my1 = new MyThread(); 6 // MyThread my2 = new MyThread(); 7 // my1.setName("my1"); 8 // my2.setName("my2"); 9 10 MyThread my1 = new MyThread("my1"); 11 MyThread my2 = new MyThread("my2"); 12 13 my1.start(); 14 my2.start(); 15 } 16 17 } 18 19 class MyThread extends Thread { 20 @Override 21 public void run() { 22 // TODO Auto-generated method stub 23 for (int i = 0; i < 1000; i++) { 24 System.out.println(getName() + ":" + i); 25 } 26 } 27 28 public MyThread(){ 29 super(); 30 } 31 32 public MyThread(String name){ 33 super(name); 34 } 35 }
2.3.线程调度
设置优先级,但是线程优先级也只是标识线程获得CPU控制权的几率高。
1 public class Demo { 2 3 public static void main(String[] args) { 4 // TODO Auto-generated method stub 5 6 MyThread my1 = new MyThread("my1"); 7 MyThread my2 = new MyThread("my2"); 8 9 System.out.println(my1.getName()+"---"+my1.getPriority()); 10 System.out.println(my2.getName()+"---"+my2.getPriority()); 11 12 my1.setPriority(1); 13 my2.setPriority(10); 14 15 my1.start(); 16 my2.start(); 17 } 18 19 } 20 21 class MyThread extends Thread { 22 @Override 23 public void run() { 24 // TODO Auto-generated method stub 25 for (int i = 0; i < 1000; i++) { 26 System.out.println(getName() + ":" + i); 27 } 28 } 29 public MyThread(String name){ 30 super(name); 31 }
2.4.线程休眠
1 public class Demo { 2 3 public static void main(String[] args) { 4 // TODO Auto-generated method stub 5 6 MyThread my1 = new MyThread("my1"); 7 MyThread my2 = new MyThread("my2"); 8 9 my1.start(); 10 my2.start(); 11 } 12 13 } 14 15 class MyThread extends Thread { 16 @Override 17 public void run() { 18 // TODO Auto-generated method stub 19 for (int i = 0; i < 1000; i++) { 20 System.out.println(getName() + ":" + i); 21 try { 22 Thread.sleep(1000);//这个异常只能try-catch处理,因为父类的run方法没有抛出异常,子类重写方法也不能抛出异常 23 } catch (InterruptedException e) { 24 // TODO Auto-generated catch block 25 e.printStackTrace(); 26 } 27 } 28 } 29 30 public MyThread(String name){ 31 super(name); 32 } 33 }
2.5.线程加入
指的是调用join方法的线程执行完了,下面的程序才能执行。
1 public static void main(String[] args) { 2 // TODO Auto-generated method stub 3 4 MyThread my1 = new MyThread("my1"); 5 MyThread my2 = new MyThread("my2"); 6 MyThread my3 = new MyThread("my3"); 7 8 my1.start(); 9 try { 10 my1.join(); 11 } catch (InterruptedException e) { 12 // TODO Auto-generated catch block 13 e.printStackTrace(); 14 } 15 my2.start(); 16 try { 17 my2.join(); 18 } catch (InterruptedException e) { 19 // TODO Auto-generated catch block 20 e.printStackTrace(); 21 } 22 my3.start(); 23 }
join的用法可以参考:java多线程 join方法以及优先级方法,Java多线程中join方法的理解。
(太长不看版= =:join方法就是要等这个自己这个线程走完了,调用启动自己这个线程的主线程才能继续往下走,其他线程不管,具体的可以试试下面的代码)
1 public class Demo { 2 3 public static void main(String[] args) { 4 MyThread my1 = new MyThread("my1"); 5 MyThread my2 = new MyThread("my2"); 6 MyThread my3 = new MyThread("my3"); 7 8 my1.start(); 9 my2.start(); 10 try { 11 my1.join(); 12 } catch (InterruptedException e) { 13 // TODO Auto-generated catch block 14 e.printStackTrace(); 15 } 16 for(int i=0;i<10000;i++){ 17 System.out.println("main"); 18 } 19 my3.start(); 20 } 21 }
大概就这个意思
2.6.线程礼让
只能让线程的执行更加和谐,但不能保证绝对谦让。
public class Demo { public static void main(String[] args) { MyThread my1 = new MyThread("my1"); MyThread my2 = new MyThread("my2"); MyThread my3 = new MyThread("my3"); my1.start(); my2.start(); // my3.start(); } } class MyThread extends Thread { @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < 1000; i++) { System.out.println(getName() + ":" + i); Thread.yield(); } } public MyThread(String name) { super(name); } }
2.7.守护线程
将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。该方法必须在启动线程前调用。该方法首先调用该线程的 checkAccess
方法,且不带任何参数。这可能抛出 SecurityException
(在当前线程中)。
抛出:IllegalThreadStateException
- 如果该线程处于活动状态。
SecurityException
- 如果当前线程无法修改该线程。
public class Demo { public static void main(String[] args) { MyThread my1 = new MyThread("my1"); MyThread my2 = new MyThread("my2"); MyThread my3 = new MyThread("my3"); my1.setDaemon(true); my2.setDaemon(true); my3.setDaemon(true); my1.start(); my2.start(); my3.start(); for(int i=0;i<5;i++){ System.out.println("main"); } } }
2.8.中断线程
stop方法已经不建议使用了。然而Interupt方法我也没太搞懂= =
import java.util.Date; public class Demo { public static void main(String[] args) { MyThread my1 = new MyThread("my1"); my1.start(); try { Thread.sleep(3000); my1.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("线程终止"); } // my1.stop(); } } class MyThread extends Thread { @Override public void run() { System.out.println("开始执行:" + new Date()); try { Thread.sleep(10000); } catch (InterruptedException e) { System.out.println("线程终止"); } System.out.println("结束执行:" + new Date()); } public MyThread(String name) { super(name); } }
2017.4.28
(CZ深入浅出Java基础)线程笔记