多线程常用操作方法:
1:线程的命名与取得
class MyThread implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
public class Test {
public static void main(String[] args) throws Exception {
MyThread mt = new MyThread() ;
new Thread(mt,"线程A").start() ; // 设置了线程的名字
new Thread(mt).start() ; // 未设置线程名字
new Thread(mt).start() ; // 未设置线程名字
new Thread(mt).start() ; // 未设置线程名字
new Thread(mt).start() ; // 未设置线程名字
new Thread(mt,"线程B").start() ; // 设置了线程的名字
}
}
//运行结果:
线程A
Thread-3
线程B
Thread-2
Thread-1
Thread-0
2:观察下面程序
class MyThread implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
public class Test {
public static void main(String[] args) throws Exception {
MyThread mt = new MyThread() ;
new Thread(mt,"线程对象").start() ; // 设置了线程的名字
mt.run(); // 对象直接调用run()方法
}
}
//运行结果
main
线程对象
上述的截图是只是在主方法中执行了一些代码。然后就启动了一个JVM进程。
3:主线程分为若干个子线程
在任何的开发之中,主线程可以创建若干个子线程,创建子线程的目的是可以将一些复杂逻辑或比较耗时的逻辑交由子线程处理:
public class Test {
public static void main(String[] args) throws Exception {
System.out.println("1、执行操作任务一。");
int temp = 0 ;
for (int x = 0 ; x < Integer.MAX_VALUE ; x ++) {
temp += x ;
}
System.out.println("2、执行操作任务二。");
System.out.println("n、执行操作任务N。");
}
}
//执行结果
1、执行操作任务一。
2、执行操作任务二。
n、执行操作任务N。
上述代码的执行效果:在第一条语句执行输出“1、执行操作任务一。”后,会停顿以下,再执行后续的代码。
耗时的操作不应该再程序的主体之中;应该启动一个子线程,那么主线程执行就会很快,子线程去耗时。
public class Test {
public static void main(String[] args) throws Exception {
System.out.println("1、执行操作任务一。");
new Thread(()->{ // 子线程负责统计
int temp = 0 ;
for (int x = 0 ; x < Integer.MAX_VALUE ; x ++) {
temp += x ;
}
}).start();
System.out.println("2、执行操作任务二。");
System.out.println("n、执行操作任务N。");
}
}
实际开发之中就是主线程负责流程的控制,而子线程负责耗时操作。
就像微博上的操作,一个线程负责刷新,一个线程负责呈现微博内容供观看;刷新不会影响浏览。
4:线程的休眠
休眠时间一到,程序会立即恢复执行。
public class Test {
public static void main(String[] args) throws Exception {
new Thread(()->{
for (int x = 0 ; x < 10 ; x ++) {
System.out.println(Thread.currentThread().getName() + "、x = " + x);
try {
Thread.sleep(1000); // 暂缓执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"线程对象").start();
}
}//执行效果
一秒输出一个对象
5:线程休眠是有先后顺序的
所有的线程操作都是一个一个来的,当然不乏可能会出现很快的,但是,大部分而言,线程的操作方法里面,由于执行的顺序,优先级有先后关系,所以执行的时候并不是同时休眠,也不是同时唤醒。中间是由适当的延迟操作的。
6线程的中断
public class Test {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(()->{
System.out.println("*** 72个小时的疯狂我需要睡觉补充精力。");
try {
Thread.sleep(10000); // 预计准备休眠10秒
System.out.println("*** 睡足了,可以出去继续祸害别人了。");
} catch (InterruptedException e) {
System.out.println("敢打扰我睡觉,老子宰了你。");
}
}) ;
thread.start(); // 开始睡
Thread.sleep(3000);
if (!thread.isInterrupted()) { // 该线程中断了吗?
System.out.println("我偷偷的打扰一下你的睡眠。");
thread.interrupt(); // 中断执行
}
}
}
//执行结果
*** 72个小时的疯狂我需要睡觉补充精力。//下面的一行是在3秒之后出现的
我偷偷的打扰一下你的睡眠。
敢打扰我睡觉,老子宰了你。
7:线程的强制执行
案例:观察一个没有强制执行的程序
public class Test {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(() -> {
for (int x = 0 ; x < 10 ; x ++) {
System.out.println(Thread.currentThread().getName() + "执行、x = " + x);
}
},"玩耍的线程") ;
thread.start();
for (int x = 0 ; x < 10 ; x ++) {
System.out.println("【霸道的main线程】number = " + x);
}
}
}
//执行效果; 发现两个在抢占执行。
【霸道的main线程】number = 0
玩耍的线程执行、x = 0
【霸道的main线程】number = 1
玩耍的线程执行、x = 1
【霸道的main线程】number = 2
玩耍的线程执行、x = 2
玩耍的线程执行、x = 3
玩耍的线程执行、x = 4
玩耍的线程执行、x = 5
玩耍的线程执行、x = 6
玩耍的线程执行、x = 7
玩耍的线程执行、x = 8
玩耍的线程执行、x = 9
【霸道的main线程】number = 3
【霸道的main线程】number = 4
【霸道的main线程】number = 5
【霸道的main线程】number = 6
【霸道的main线程】number = 7
【霸道的main线程】number = 8
【霸道的main线程】number = 9
public class Test {
public static void main(String[] args) throws Exception {
Thread mainThread = Thread.currentThread() ; // 获得主线程
Thread thread = new Thread(() -> {
for (int x = 0 ; x < 10 ; x ++) {
if (x == 3) { // 现在霸道的线程来了
try {
mainThread.join();// 霸道线程要先执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "执行、x = " + x);
}
},"玩耍的线程") ;
thread.start();
for (int x = 0 ; x < 10 ; x ++) {
Thread.sleep(100);
System.out.println("【霸道的main线程】number = " + x);
}
}
}
8:线程的礼让
线程的礼让指的是先将资源礼让出去让别的线程先执行。线程的礼让可以使用Thread中提供的方法;
public class Test {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(() -> {
for (int x = 0 ; x < 10 ; x ++) {
if (x % 3 == 0) {
Thread.yield(); // 线程礼让
System.out.println("### 玩耍的线程礼让执行 ###");
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "执行、x = " + x);
}
},"玩耍的线程") ;
thread.start();
for (int x = 0 ; x < 10 ; x ++) {
Thread.sleep(100);
System.out.println("【霸道的main线程】number = " + x);
}
}
}
9:线程的优先级
优先级高的有可能先执行,而不是绝对先执行。
public class Test {
public static void main(String[] args) throws Exception {
Runnable run = ()->{
for (int x = 0 ; x < 10 ; x ++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "执行。");
}
} ;
Thread threadA = new Thread(run,"线程对象A") ;
Thread threadB = new Thread(run,"线程对象B") ;
Thread threadC = new Thread(run,"线程对象C") ;
threadA.setPriority(Thread.MIN_PRIORITY);
threadB.setPriority(Thread.MIN_PRIORITY);
threadC.setPriority(Thread.MAX_PRIORITY);
threadA.start();
threadB.start();
threadC.start();
}
}
主线程的优先级(主方法也是一个线程)
public class ThreadDemo {
public static void main(String[] args) throws Exception {
System.out.println(new Thread().getPriority());
System.out.println(Thread.currentThread().getPriority());
}
}
//5
5
主线程属于中等优先级,而默认创建的线程也是中等优先级。