多线程随笔
多线程:
多线程是读任务的 一种特别的形式,但多线程使用了更小的资源开销。
java 给多线程编程提供了内置的支持,一条线程指的是进程中一个单一顺序的控制流,
一个进程中可以并发多个线程,每条线程并行执行不同的任务。
开启多线程的目的:
比如在某些时候需要执行一些耗时任务、希望某些程序看起来同时运行、希望完成某个特定的子任务
或防止线程阻塞等情况下,我们就需要开启多线程完成我们想要达到的某种效果。
进程和线程:**
进程:进程就是正在执行的程序。
线程:线程就是一条独立的执行路径。
开启线程虽然降低了效率,但是提高了CPU的使用率,更加合理的利用CPU的 使用率。
CPU执行原理:
在真实环境下,CPU能够同时执行多个程序,本质知识在同一时间刻度上执行一条线程的一条原子性语句,
只是CPU切换执行速度非常快,我们无法察觉,让我们感觉是在同时执行一样。
多线程的实现方式:
方式一:继承Thread类
1、自定义类MyThread继承Thread类。
2、MyThread类里面重写run()方法。
3、创建线程对象。
4、启动线程。
注:
1、启动线程使用的是start()方法而不是run()方法
方式二:实现Runnable接口
1、自定义类MyRunnable实现Runnable接口。
2、重写run()方法
3、创建MyRunnable类的对象
4、创建Thread类的对象,并把步骤3创建的对象作为构造参数传递。
5、启动线程。
实现接口方式的好处
1、可以避免由于Java单继承带来的局限性。
2、适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效分离,较好的体现了面
向对象的设计思想。
下方是上面方式一和方式二的示例代码:
package com.ccv.cn; public class ThreadDome01 { public static void main(String[] args) { //创建线程对象,在主方法输出 ShuJuThread sjt= new ShuJuThread(); Thread t = new Thread(sjt); //用start()方法开启线程 t.start(); //创建线程对象 ThreadDome t2 = new ThreadDome("name:老虎!"); //开启线程 t2.start(); } } class ThreadDome extends Thread { private Thread a; private String Name; ThreadDome(String name) { Name = name; } public void run() { try { for (int i = 1; i <=3; i++) { System.out.println(Name + i); //让线程休眠3秒 Thread.sleep(3000); } }catch (InterruptedException e) { //出现问题就中断 System.out.println("中断"); } //没问题执行完循环就退出 System.out.println("退出"); } public void shuju() { //判断a是否为空 if (a == null) { a = new Thread(this.Name); a.start(); } } } //自定义ShuJuThread类实现Runnable接口 class ShuJuThread implements Runnable { //重写run方法 @Override public void run() { //遍历1~100 for (int i = 1; i <=100; i++) { System.out.println("启动子线程:" + i); } } }
线程的常用方法:
设置和获取线程名称:
1、Thread(String name) 分配新的 Thread 对象。
2、Thread(Runnable target, String name) 分配新的 Thread 对象。
通过线程的成员方法:
1、public final String getName()
2、public final void setName(String name)
通过静态方法
1、public static Thread currentThread() 可以获取任意方法所在的线程名称
2、Thread.currentThread().getName(); 可以获取主线程的线程名称
设置和获取线程的优先级:
1、public final int getPriority()
2、public final void setPriority(int newPriority)
线程休眠:
public static void sleep(long millis)
示例代码如下:
public class ThreadDemo05 { public static void main(String[] args) { Thread t = new Thread(new SleepThread(), "时钟线程"); t.start(); } } // 利用线程休眠模拟时钟 class SleepThread implements Runnable { @Override public void run() { while (true) { String dateStr = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()); System.out.println(Thread.currentThread().getName() + "的当前时间为: " + dateStr); // 休眠时间为3秒 try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
中断线程:
1、public final void stop()
2、public void interrupt()
示例代码如下:
public static void main(String[] args) { Thread t = new Thread(new StopThread(), "鬼"); t.start(); try { Thread.sleep(3000); t.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } } class StopThread implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName() + "开始时间:" + new Date()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); System.exit(0); } System.out.println(Thread.currentThread().getName() + "结束时间:" + new Date()); }
后台线程:
当虚拟机中的用户线程全部退出运行时,守护线程没有服务的对象后,JVM也就退出了
public final void setDaemon(boolean on)
示例代码如下:
package com.ccv.cn; //后台线程示例如下 public class ThreadDemo04 { public static void main(String[] args) { //创建线程对象 DaemonThread t1 = new DaemonThread(); DaemonThread t2 = new DaemonThread(); //为对象赋值 t1.setName("小高"); t2.setName("小黄"); //使用setDaemon()方法 t1.setDaemon(true); t2.setDaemon(true); //开启线程 t1.start(); t2.start(); Thread.currentThread().setName("学生"); for (int i = 1; i <= 10; i++) { System.out.println(Thread.currentThread().getName() + "=" + i); } } } class DaemonThread extends Thread { @Override public void run() { for (int i = 1; i <= 50; i++) { System.out.println(Thread.currentThread().getName() + "=" + i); } } }
线程加入:
public final void join()
示例代码如下:
package com.ccv.cn; public class ThreadDemo03 { public static void main(String[] args) { //创建线程对象 JoinThread t1 = new JoinThread(); JoinThread t2 = new JoinThread(); //为对象赋值 t1.setName("小明"); t2.setName("小红"); t1.start(); try { //使用join();方法加入线程 t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } t2.start(); try { t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } class JoinThread extends Thread { @Override public void run() { for (int i = 1; i <= 50; i++) { System.out.println(getName() + "=" + i); } } }
线程礼让:
public static void yield()
示例代码如下:
package com.ccv.cn; //线程礼让 public class ThreadDemo02 { public static void main(String[] args) { //创建线程对象 StudentThread t1 = new StudentThread(); StudentThread t2 = new StudentThread(); StudentThread t3 = new StudentThread(); //赋值 t1.setName("小明"); t2.setName("小红"); t3.setName("小丽"); //开启线程 t1.start(); t2.start(); t3.start(); } } class StudentThread extends Thread { //重写run方法 @Override public void run() { for (int i = 1; i <= 50; i++) { System.out.println(getName() + ":" + i); Thread.yield(); } } }