多线程---线程实现
并行和并发:
并行:在同一时刻,有多个指令在多个CPU上同时执行
并发:在同一时刻,有多个指令在单个CPU上交替执行
进程和线程:
进程:进程是正在运行的程序
- 是系统进行资源分配和调用的独立单位
- 每一个进程都有它自己的内存空间和系统资源
线程:是进程中单个顺序控制流,是一条执行路径
关系:
单线程:一个进程如果只有一个线程,则成为单线程程序
多线程:一个进程如果有多个线程,则成为多线程程序
run()方法:
为什么要重写run();方法?
- 因为run();方法是用来封装被线程执行的代码
run();方法和start();方法的区别:
- run();封装线程执行的代码,直接调用相当于普通方法的调用,并没有开启线程
- start();启动线程,然后由JVM调用此线程的run();方法
多线程的实现方式:
代码演示:
1 public class MyRunnable implements Runnable { 2 @Override 3 public void run() { 4 for(int i=0; i<100; i++) { 5 System.out.println(Thread.currentThread().getName()+":"+i); 6 } 7 } 8 } 9 public class MyRunnableDemo { 10 public static void main(String[] args) { 11 //创建MyRunnable类的对象 12 MyRunnable my = new MyRunnable(); 13 14 //创建Thread类的对象,把MyRunnable对象作为构造方法的参数 15 //Thread(Runnable target) 16 // Thread t1 = new Thread(my); 17 // Thread t2 = new Thread(my); 18 //Thread(Runnable target, String name) 19 Thread t1 = new Thread(my,"坦克"); 20 Thread t2 = new Thread(my,"飞机"); 21 22 //启动线程 23 t1.start(); 24 t2.start(); 25 } 26 }
代码演示:
1 public class MyCallable implements Callable<String> { 2 @Override 3 public String call() throws Exception { 4 for (int i = 0; i < 100; i++) { 5 System.out.println("跟女孩表白" + i); 6 } 7 //返回值就表示线程运行完毕之后的结果 8 return "答应"; 9 } 10 } 11 public class Demo { 12 public static void main(String[] args) throws ExecutionException, InterruptedException { 13 //线程开启之后需要执行里面的call方法 14 MyCallable mc = new MyCallable(); 15 16 //Thread t1 = new Thread(mc); 17 18 //可以获取线程执行完毕之后的结果.也可以作为参数传递给Thread对象 19 FutureTask<String> ft = new FutureTask<>(mc); 20 21 //创建线程对象 22 Thread t1 = new Thread(ft); 23 24 String s = ft.get(); 25 //开启线程 26 t1.start(); 27 28 //String s = ft.get(); 29 System.out.println(s); 30 } 31 }
三种实现方式的对比:
获取当前线程对象:
Thread.currentThread;
sleep方法线程休眠:
代码如下:
1 public class MyRunnable implements Runnable { 2 @Override 3 public void run() { 4 for (int i = 0; i < 100; i++) { 5 try { 6 Thread.sleep(100); 7 } catch (InterruptedException e) { 8 e.printStackTrace(); 9 } 10 11 System.out.println(Thread.currentThread().getName() + "---" + i); 12 } 13 } 14 } 15 public class Demo { 16 public static void main(String[] args) throws InterruptedException { 17 /*System.out.println("睡觉前"); 18 Thread.sleep(3000); 19 System.out.println("睡醒了");*/ 20 21 MyRunnable mr = new MyRunnable(); 22 23 Thread t1 = new Thread(mr); 24 Thread t2 = new Thread(mr); 25 26 t1.start(); 27 t2.start(); 28 } 29 }
线程优先级:
守护线程;
- void setDaemon(boolean on)
- 将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出
代码演示:
1 public class MyThread1 extends Thread { 2 @Override 3 public void run() { 4 for (int i = 0; i < 10; i++) { 5 System.out.println(getName() + "---" + i); 6 } 7 } 8 } 9 public class MyThread2 extends Thread { 10 @Override 11 public void run() { 12 for (int i = 0; i < 100; i++) { 13 System.out.println(getName() + "---" + i); 14 } 15 } 16 } 17 public class Demo { 18 public static void main(String[] args) { 19 MyThread1 t1 = new MyThread1(); 20 MyThread2 t2 = new MyThread2(); 21 22 t1.setName("女神"); 23 t2.setName("备胎"); 24 25 //把第二个线程设置为守护线程 26 //当普通线程执行完之后,那么守护线程也没有继续运行下去的必要了. 27 t2.setDaemon(true); 28 29 t1.start(); 30 t2.start(); 31 } 32 }
迎风少年