Java多线程编程一(一些线程的知识)
进程和线程的概念及线程的优点
进程:可简单理解为Window上的一个应用程序如:qq.exe
线程:可简单理解为qq.exe中的一个后台下载程序等
线程的优点:在同一时间可以同时进行多个任务的工作,很方便,高效率的节省工作时间。如你在聊q的同时,听歌,下载文件,聊天。。。
使用多线程
(1)继承Thread类重写run()方法:
public class MyThread extends Thread {
@Override
public void run() {
super.run();
System.out.println("需要执行的任务");
}
public static void main(String[] args) {
Thread thread = new MyThread();
thread.start();
System.out.println("运行结束!");
}
}
(2)实现Runnable接口:
public class MyThread implements Runnable {
public void run() {
System.out.println("需要执行的任务");
}
public static void main(String[] args) {
Thread thread = new Thread(new MyThread());
thread.start();
System.out.println("运行结束!");
}
}
实例变量和线程安全
自定义的线程类中实例变量针对其他线程可以有共享和不共享之分,这在多个线程之间进行交互时是个重要的技术点。
不共享数据的情况下:
public class MyThread extends Thread {
private int count = 5;
public MyThread(String name) {
this.setName(name);
}
@Override
public void run() {
System.out.println("需要执行的任务");
while (count > 0) {
count--;
System.out.println("由:" + Thread.currentThread().getName() + "计算,count=" + count);
}
}
public static void main(String[] args) {
MyThread a = new MyThread("A");
MyThread b = new MyThread("B");
MyThread c = new MyThread("C");
a.start();
b.start();
c.start();
System.out.println("运行结束!");
}
}
由于每个实例都有属于自己的变量count,计算互不干扰,既不共享数据,所有也就不会出现错误数据的情况,是线程安全的。
共享数据的情况下:
public class MyThread extends Thread {
private static int count = 5;
@Override
public void run() {
System.out.println("需要执行的任务");
while (count > 0) {
count--;
System.out.println("由:" + Thread.currentThread().getName() + "计算,count=" + count);
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread a = new Thread(myThread, "A");
Thread b = new Thread(myThread, "B");
Thread c = new Thread(myThread, "C");
a.start();
b.start();
c.start();
System.out.println("运行结束!");
}
}
运行结果:
需要执行的任务
需要执行的任务
由:A计算,count=3
由:B计算,count=3
由:A计算,count=1
由:B计算,count=1
由:A计算,count=0
运行结束!
需要执行的任务
由结果我们发现,出现了线程A和线程B取出的值为同一个值,产生了非线程安全的问题。在JVM中,i--
分为如下三步:
- 1、取得原有值i
- 2、计算i-1
- 3、对i进行赋值
在这三个步骤中,如果有多个线程同时访问,那么一定会出现非线程安全问题
部分常用方法
currentThread()
: 返回代码正在被哪个线程调用的信息isAlive()
: 判断当前线程是否处于活动状态,活动状态就是线程已经启动且尚未终止,线程处于正在运行或准备开始运行的状态就认为是"存活"的sleep()
: 指定毫秒数内,让‘当前’正在执行的线程休眠(暂停执行)getId()
: 获得线程的唯一标识。
停止线程
- interrupt(): 仅仅是在当前线程打了一个中断的标记,并不是真正的停止线程。
判断线程是否停止状态:
this.interrupt(); //测试当前线程是否已经中断,线程的中断状态由该方法清楚,当前线程是指运行this.interrupt()方法的线程
this.isInterrupted(); //测试线程是否已经中断
- 异常法(抛出异常来终止线程的运行)
- 如果沉睡中停止线程,会发生异常
- 暴力停止
stop()
废弃 - return停止线程
- 变量控制,跳出循环
线程的优先级
在操作系统中,线程可以划分优先级,优先级较高的线程得到cpu的资源较多,也就是cpu优先执行优先级较高的线程对象中的任务。
设置线程的优先级有助于帮“线程规划器”确定在下一次选择哪一个线程来优先执行。
设置线程的优先级使用setPriority()
方法。
JDK使用3个常量来预置定义优先级的值,代码如下:
/**
* 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;
- 线程的优先级具有继承性:线程A启动线程B,A与B具有相同的优先级。
- 优先级具有规则性:大部分高优先级的线程比低优先级线程先执行,并不是一定就会比低优先级的先执行完。
守护线程
守护线程是一种特殊的线程,他的特性有“陪伴”的含义,当进程不存在非守护线程了,则守护线程自动销毁。典型的守护线程就是垃圾回收线程,当进程中没有非守护线程了,那么垃圾回收线程也就没有存在的必要了,自动销毁。
“守护线程”:任何一个守护线程都是整个JVM中所有非守护线程的“保姆”,只要当前JVM实例中存在任何一个非守护线程没有结束,守护线程就在工作,只有当最后一个非守护线程结束时,守护线程才会随着JVM一同结束工作。
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/13/java-multi-threading-programming-basic/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论