Java笔记-多线程相关
ava多线程和C++里面的多线程有些地方不一样。毕竟套了一个java虚拟机。对此记录下。Java语言内置多线程支持:一个java程序实际上是一个JVM进程。JVM用一个主线程来执行main()方法。在main()方法中又可以启动多个进程。Java多线程创建MyThread类逻辑:1.从Thread派生;2.覆写run...
ava多线程和C++里面的多线程有些地方不一样。
毕竟套了一个java虚拟机。对此记录下。
Java语言内置多线程支持:
一个java程序实际上是一个JVM进程。
JVM用一个主线程来执行main()方法。
在main()方法中又可以启动多个进程。
Java多线程创建MyThread类逻辑:
1. 从Thread派生;
2. 覆写run()方法;
3. 创建MyThread实例;
4. 调用start()启动线程。
创建一个线程对象,并启动一个线程。
Thread t = new Thread();
t.start();
如果一个类已经从某个类派生,无法从Thread继承,那么需要的逻辑:
1. 实现Runable接口;
2. 覆写run()方法;
3. 在main()方法中创建Runnable实例;
4. 创建Thread实例并传入Runnable;
5. 调用start()启动线程。
如下代码:
class Thread1 extends Thread{
String name;
public Thread1(String name){
this.name = name;
}
@Override
public void run() {
for(int i = 0; i < 5; i++){
System.out.println("[" + Thread.currentThread().getId() + "]" + " " + name);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main1 {
public static void main(String[] args){
Thread1 t1 = new Thread1("线程1");
t1.start();
Thread1 t2 = new Thread1("线程2");
t2.start();
System.out.println("Over!");
}
}
程序运行截图如下:
这里要注意:为什么主线程已经结束了,子线程还在跑。
Java没有严格的主线程和子线程的概念。除非主线程终止了子线程,否则子线程会一直执行。
下面是线程的优先级:
可以对线程设置优先级Thread.setPriority(int n)// 1~10,默认为5
优先级高的线程被操作系统调度优先级高
不能通过设置优先级来确保先后顺序。
Java多线程的状态:
New(新创建)、Runnable(运行中)、Blocked(被阻塞)、Waiting(等待)、Timed Waiting(计时等待)、Terminated(已种子)
线程终止的原因:
run()方法执行到return语句返回(线程正常结束)
因为未捕获的移除导致线程终止(线程意外终止)
对某个线程的Thread实例调用stop()方法强制终止(不推荐)
如下代码:
class MyThread extends Thread{
String name;
public MyThread(String name){
this.name = name;
}
@Override
public void run() {
for(int i = 0; i < 5; i++){
System.out.println("[" + Thread.currentThread().getId() + "]" + " " + name);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main2 {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread("线程");
System.out.println("线程");
myThread.start();
myThread.join(); //等待myThread执行结束
System.out.println("END");
}
}
程序运行截图如下:
如果线程需要执行一个长时间任务,就可能需要能中断线程。
中断线程就是其他线程给该线程发一个信号,该线程收到信号后结束执行run()方法。
中断线程需要通过检测inlnterrupted()标志。
其他线程通过调用interrupt()方法中断该线程。
代码如下:
class MyThread2 extends Thread{
@Override
public void run() {
while(!isInterrupted()){
System.out.println("[" + Thread.currentThread().getId() + "]" + " " + "Hello");
}
}
}
public class Main3 {
public static void main(String[] args) throws InterruptedException {
MyThread2 myThread = new MyThread2();
myThread.start();
Thread.sleep(1000);
myThread.interrupt();
}
}
程序运行截图如下:
如果线程处于等待状态,该线程会捕获InterruptedException
捕获到InterruptedException说明有其他线程对其调用了interrupt()方法。通常情况下该线程会立刻结束运行
代码如下:
class MyThread3 extends Thread{
@Override
public void run() {
while(!isInterrupted()){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main4 {
public static void main(String[] args){
}
}
还可以设置running标志位,这个就和C++里面常用的方法一样。外部通过修改一个成员的状态来让其退出。
但是不同的是,java有个java虚拟机。这个和C++里面的不一样。
要用volatile关键字,如下:public volatile boolean running = false;
Java虚拟机里面,有给主内存的概念,其实任意变量都是在主内存中,当创建了线程后,会在线程中有给变量,这个变量同时也会在主内存中,有一个变量与之对于。
如下:
这样在跟新的时候,就会存中误差。所以就需要volatile关键字:
volatile关键字的目的是告诉虚拟机:
每次访问变量时,总是获取主内存的最新值。
每次修改变量后,立刻回写到主内存。
Volatile关键字解决的是可见性问题:
当一个线程修改了某个共享变量的值,其他线程能够立刻看到修改后的值。
代码如下:
class MyThread5 extends Thread{
public volatile boolean running = true;
@Override
public void run() {
while(running){
System.out.println("Hello");
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
e.printStackTrace();
System.out.println("InterruptedException");
break;
}
}
}
}
public class Main5 {
public static void main(String[] args) throws InterruptedException {
MyThread5 myThread5 = new MyThread5();
myThread5.start();
Thread.sleep(1000);
myThread5.running = false;
System.out.println("end");
}
}
程序运行截图如下:
源码打包下载地址:https://github.com/fengfanchen/Java/tree/master/MultiThreadInJav
更多推荐
所有评论(0)