您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
【第9章:多线程】_线程常用操作方法
发布时间:2020-12-20 19:42:24编辑:雪饮阅读()
获取系统默认分配的当前线程的线程名称
class MyThread implements Runnable{
public void run(){
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName());
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
new Thread(mt1).start();
new Thread(mt1).start();
new Thread(mt1).start();
}
}
D:\>javac TestJava.java
D:\>java TestJava
Thread-0
Thread-0
Thread-1
Thread-1
Thread-1
Thread-0
Thread-2
Thread-2
Thread-2
可见系统自动设置的默认线程名称是类似于主键自增的方案
手动指定线程名称
在Thread类的构造方法中有一个是拥有两个参数的构造方法,该构造方法的第二个参数就是线程名称。
class MyThread implements Runnable{
public void run(){
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName());
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
new Thread(mt1).start();
new Thread(mt1,"线程A").start();
new Thread(mt1,"线程B").start();
}
}
D:\>javac TestJava.java
D:\>java TestJava
Thread-0
Thread-0
Thread-0
线程B
线程B
线程B
线程A
线程A
线程A
由Runnable接口的实现类所构造出来的线程若直接调用则该线程就属于main线程
class MyThread implements Runnable{
public void run(){
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName());
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
new Thread(mt1).start();
mt1.run();
}
}
D:\>javac TestJava.java
D:\>java TestJava
main
main
main
Thread-0
Thread-0
Thread-0
这里发现由主方法直接调用线程则线程名称是main,其实主方法也是一个线程,就是main线程
isAlive
isAlive用于判断一个线程是否还在存活
class MyThread implements Runnable{
public void run(){
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName());
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
Thread t=new Thread(mt1);
System.out.println("线程开始执行之前:"+t.isAlive());
t.start();
System.out.println("线程开始执行之后:"+t.isAlive());
}
}
D:\>javac TestJava.java
D:\>java TestJava
线程开始执行之前:false
线程开始执行之后:true
Thread-0
Thread-0
Thread-0
强制运行
首先我们来看一段程序
class MyThread implements Runnable{
public void run(){
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName()+"运行,i="+i);
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
Thread t=new Thread(mt1);
t.start();
System.out.println("t线程执行结束之后");
}
}
D:\>javac TestJava.java
D:\>java TestJava
t线程执行结束之后
Thread-0运行,i=0
Thread-0运行,i=1
Thread-0运行,i=2
我们发现如果按照正常的代码执行流程,这里应该是最后输出” t线程执行结束之后”结果我们发现” t线程执行结束之后”竟然是执行在第一位了。
这是因为多线程情况下不会按照语法顺序而是按照那个线程先被分配到了cpu时间片,然后那个线程就优先执行,那么这里输出的这第一位的这句话是因为它默认在主线程上,那么主线程可能优先级更高吧。
那么接下来我们再来看看另外一段程序
class MyThread implements Runnable{
public void run(){
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"运行,i="+i);
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
Thread t=new Thread(mt1);
t.start();
for(int i=0;i<10;i++){
if(i>5){
try{
t.join();
}catch(InterruptedException e){
}
}
}
System.out.println("t线程执行结束之后");
}
}
D:\>javac TestJava.java
D:\>java TestJava
Thread-0运行,i=0
Thread-0运行,i=1
Thread-0运行,i=2
Thread-0运行,i=3
Thread-0运行,i=4
Thread-0运行,i=5
Thread-0运行,i=6
Thread-0运行,i=7
Thread-0运行,i=8
Thread-0运行,i=9
t线程执行结束之后
该段程序中已经按照我们一般的语法顺序进行输出的。这是因为主线程中当t线程开始执行之后主线程也继续执行,当主线程执行到i=6的时候此时t线程也已经执行到i=6了,但是这个时候主线程中又将t线程设置位强制执行了(就是上面t.join()),强制执行的作用就是让指定线程必须先执行结束,然后才腾出时间片给cpu,等待cpu重新分配给其它线程。
Thread.sleep
Thread类中有静态方法sleep可以提供让某个线程休眠,Thread.sleep语句所在线程休眠,接收一个毫秒的参数。
class MyThread implements Runnable{
public void run(){
for(int i=0;i<10;i++){
try{
Thread.sleep(500);
}catch(InterruptedException e){
}
System.out.println(Thread.currentThread().getName()+"运行,i="+i);
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
Thread t=new Thread(mt1);
t.start();
System.out.println("t线程执行结束之后");
}
}
D:\>javac TestJava.java
D:\>java TestJava
t线程执行结束之后
Thread-0运行,i=0
Thread-0运行,i=1
Thread-0运行,i=2
Thread-0运行,i=3
Thread-0运行,i=4
Thread-0运行,i=5
Thread-0运行,i=6
Thread-0运行,i=7
Thread-0运行,i=8
Thread-0运行,i=9
运行结果会发现很卡顿,一顿一顿的出每一行的结果。
interrupt
interrupt用于终止线程
class MyThread implements Runnable{
public void run(){
for(int i=0;i<10;i++){
try{
Thread.sleep(1000);
System.out.println("2、已完成休眠");
}catch(InterruptedException e){
System.out.println("3、休眠被终止");
}
System.out.println(Thread.currentThread().getName()+"运行,i="+i);
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
Thread t=new Thread(mt1);
t.start();
t.interrupt();
}
}
D:\>java TestJava
3、休眠被终止
Thread-0运行,i=0
2、已完成休眠
Thread-0运行,i=1
2、已完成休眠
Thread-0运行,i=2
2、已完成休眠
Thread-0运行,i=3
2、已完成休眠
Thread-0运行,i=4
2、已完成休眠
Thread-0运行,i=5
2、已完成休眠
Thread-0运行,i=6
2、已完成休眠
Thread-0运行,i=7
2、已完成休眠
Thread-0运行,i=8
2、已完成休眠
Thread-0运行,i=9
稍微修缮下,上面的休眠虽然被interrupt中断了,但是程序还是在执行
在休眠终止的异常捕获处return下即可
class MyThread implements Runnable{
public void run(){
for(int i=0;i<10;i++){
try{
Thread.sleep(1000);
System.out.println("2、已完成休眠");
}catch(InterruptedException e){
System.out.println("3、休眠被终止");
return;
}
System.out.println(Thread.currentThread().getName()+"运行,i="+i);
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
Thread t=new Thread(mt1);
t.start();
t.interrupt();
}
}
D:\>javac TestJava.java
D:\>java TestJava
3、休眠被终止
setDaemon
setDaemon用于将一个线程置于后台运行,所以如下代码你将看不到前台有任何输出。
class MyThread implements Runnable{
public void run(){
for(int i=0;i<10;i++){
try{
Thread.sleep(1000);
System.out.println("2、已完成休眠");
}catch(InterruptedException e){
System.out.println("3、休眠被终止");
return;
}
System.out.println(Thread.currentThread().getName()+"运行,i="+i);
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
Thread t=new Thread(mt1);
t.setDaemon(true);
t.start();
}
}
D:\>javac TestJava.java
D:\>java TestJava
线程优先级
我们先看看下面这个程序
class MyThread implements Runnable{
public void run(){
for(int i=0;i<3;i++){
System.out.println(Thread.currentThread().getName()+"运行,i="+i);
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
Thread t1=new Thread(mt1);
Thread t2=new Thread(mt1);
Thread t3=new Thread(mt1);
t1.start();
t2.start();
t3.start();
}
}
D:\>javac TestJava.java
D:\>java TestJava
Thread-0运行,i=0
Thread-0运行,i=1
Thread-0运行,i=2
Thread-2运行,i=0
Thread-2运行,i=1
Thread-2运行,i=2
Thread-1运行,i=0
Thread-1运行,i=1
Thread-1运行,i=2
可以看到我们语法顺序是线程0、线程1、线程2,而实际结果是线程0、线程2、线程1
其实线程优先级可以通过setPriority方法进行设置,该方法接收一个优先级常量
可选有:Thread.MAX_PRIORITY、Thread.NORM_PRIORITY、Thread.MIN_PRIORITY
class MyThread implements Runnable{
public void run(){
for(int i=0;i<3;i++){
try{
Thread.sleep(500);
}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"运行,i="+i);
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
Thread t1=new Thread(mt1,"线程A");
Thread t2=new Thread(mt1,"线程B");
Thread t3=new Thread(mt1,"线程C");
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.NORM_PRIORITY);
t3.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
}
}
D:\>javac TestJava.java
D:\>java TestJava
线程A运行,i=0
线程B运行,i=0
线程C运行,i=0
线程A运行,i=1
线程B运行,i=1
线程C运行,i=1
线程A运行,i=2
线程C运行,i=2
线程B运行,i=2
获取优先级
getPriority()方法可以用于获取某个线程的优先级配置
class MyThread implements Runnable{
public void run(){
for(int i=0;i<3;i++){
try{
Thread.sleep(500);
}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"运行,i="+i);
}
}
}
public class TestJava{
public static void main(String args[]){
System.out.println("主方法的优先级:"+Thread.currentThread().getPriority());
}
}
D:\>javac TestJava.java
D:\>java TestJava
主方法的优先级:5
线程优先级常量
class MyThread implements Runnable{
public void run(){
for(int i=0;i<3;i++){
try{
Thread.sleep(500);
}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"运行,i="+i);
}
}
}
public class TestJava{
public static void main(String args[]){
System.out.println("Thread.MAX_PRIORITY:"+Thread.MAX_PRIORITY);
System.out.println("Thread.NORM_PRIORITY:"+Thread.NORM_PRIORITY);
System.out.println("Thread.MIN_PRIORITY:"+Thread.MIN_PRIORITY);
}
}
D:\>javac TestJava.java
D:\>java TestJava
Thread.MAX_PRIORITY:10
Thread.NORM_PRIORITY:5
Thread.MIN_PRIORITY:1
线程礼让
一个线程的实例可以调用yield方法实现线程礼让,所谓礼让就是把自己抢占的cpu时间片礼让出去让cpu重新分配
该实验演示的时候需要结合你自己电脑的cpu个数来实验,如果你启动的线程数比较小的话,小于你的cpu个数,则就算你礼让了下次你自己又抢占到了,因为cpu个数太多,你礼让出去没有别人去抢,最后还是你自己拿去了。
那么由于我这里有12个cpu
所以我就建立了13个线程
class MyThread implements Runnable{
public void run(){
for(int i=0;i<6;i++){
if(i==3){
System.out.println("线程礼让:");
Thread.currentThread().yield();
}
System.out.println(Thread.currentThread().getName()+"运行,i="+i);
}
}
}
public class TestJava{
public static void main(String args[]){
MyThread mt1=new MyThread();
Thread t1=new Thread(mt1,"线程A");
Thread t2=new Thread(mt1,"线程B");
Thread t3=new Thread(mt1,"线程C");
Thread t4=new Thread(mt1,"线程D");
Thread t5=new Thread(mt1,"线程E");
Thread t6=new Thread(mt1,"线程F");
Thread t7=new Thread(mt1,"线程G");
Thread t8=new Thread(mt1,"线程I");
Thread t9=new Thread(mt1,"线程H");
Thread t10=new Thread(mt1,"线程O");
Thread t11=new Thread(mt1,"线程P");
Thread t12=new Thread(mt1,"线程Q");
Thread t13=new Thread(mt1,"线程M");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
t8.start();
t9.start();
t10.start();
t11.start();
t12.start();
t13.start();
}
}
关键字词:java,线程,礼让
上一篇:【第9章:多线程】_认识多线程
下一篇:〖第9章:多线程〗_线程操作范例