一,name
Thread有name属性(如果要追究原理,又牵涉到源码,还要看操作系统,麻烦,先记住,平时用的话这样就行了
,
),
创建的时候可以设置,
程序可以通过 currentThread() 取得当前线程对象,得到当前线程后也可以设置线程nam
class MyThread implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
Thread.currentThread().setName("MyThread1-1");
System.out.println(Thread.currentThread().getName());
}
}
public class test1 {
public static void main(String ar[]) {
System.out.println(Thread.currentThread().getName());
new Thread(new MyThread(),"MyThread1").start();
}
}
运行结果:
不过一般,推荐生成线程的时候命名,之后不要改了。
运行结果中:有一个名为“main”的线程,看到这里很多人就已经知道了,这个线程是“main”方法的线程,正确的。
在java运行是至少会启动两个线程:
1.main线程(也叫主线程)
2.GC线程,这个是java垃圾回收的线程
(jvw是一个进程)
二:isAlive()
线程运行时,可以通过,isAlive()方法得到当前线程是否正在运行
class MyThread implements Runnable {
@Override
public void run() {
for(int i = 0; i<10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
public class test1 {
public static void main(String ar[]) {
MyThread mt = new MyThread();
Thread t = new Thread(mt,"MyThread1");
System.out.println(t.isAlive());
t.start();
System.out.println(t.isAlive());
for(int i = 0; i<10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
System.out.println("出现的位置不定,结果不定,main循环完出现,"+t.isAlive());
}
}
三:join()
线程强制运行,
class MyThread implements Runnable {
@Override
public void run() {
for(int i = 0; i<10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
public class test1 {
public static void main(String ar[]) {
MyThread mt = new MyThread();
Thread t = new Thread(mt,"MyThread1");
t.start();
for(int i = 0; i<10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
if(i > 5) {
try {
t.join();
} catch(Exception e) {
}
}
}
}
}
四:sleep()
这个方法不用说了。。
四:interrupt()
interrupt()方法调用后,并不会退出当前线程,(这个方法,感觉没什么用),可以考虑一下下面的情况:
class MyThread5 extends Thread {
@Override
public void run() {
try {
super.sleep(6000);
} catch (Exception e) {
System.out.println("检测到异常");
}
}
}
public class test2 {
public static void main(String sr[]) {
MyThread5 t = new MyThread5();
t.start();
try {
Thread.currentThread().sleep(1000);
t.interrupt();
} catch(Exception e) {
System.out.println("main异常");
}
}
}
MyThread5 sleep(6000)
main sleep(1000)
main sleep()完成后就会interrupt() MyThread5线程,这时候MyThread5还在sleep(),被中断就会受异常就能检测到异常,这时候MyThread5就会中断sleep()继续执行下面的代码。
五,线程的优先级
Thread类中有三个static int 类型的常量,表示线程的优先级
可以通过代码输出这些常量的值
class MyThread5 extends Thread {
@Override
public void run() {
System.out.println(this.getName() + " 运 行 " + this.getPriority());
}
}
class MyThread6 extends Thread {
@Override
public void run() {
System.out.println(this.getName() + " 运 行 " + this.getPriority());
}
}
public class test2 {
public static void main(String sr[]) {
MyThread5 t5 = new MyThread5();
MyThread6 t6 = new MyThread6();
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);
t5.start();
t6.start();
System.out.println(Thread.currentThread().getName() + " 运 行 " + Thread.currentThread().getPriority());
}
}
运行结果:
明显值越大的优先级越高
Thread.MAX_PRIORITY 10 > Thread.NORM_PRIORITY 5 > Thread.MIN_PRIORITY 1
从结果也可以看出main和一个普通的线程一样,他的优先级是 5 中等优先级。
可以通过 setPriority(int PRIORITY); 来设置线程的优先级,但并不是优先级高的线程一定能够先执行,具体的还是要看谁先的到资源。
五,Thread和Runnable
Thread与Runnable的区别:
通过这个图可以知道,Thread也是实现Runnable接口的一个类,
这样我们自己写的线程类MyThread,和java提供的Thread就有联系了。他们都是实现了Runnable接口的,而Runnable这个接口只要求我们重写run()方法就行了,因为它里面只有一个抽象的方法run()
你可以理解为Thread类实现了Runnable接口,并且还新增加了很多方法,这些方法都是实现线程操作必须的方法,而这个线程要干什么是程序员需要考虑的,程序员只需要提供run()方法即可。
所有推荐实现Runnable接口,然后通过Thread(Runnable target) 来创建一个线程。这种方法类似于模板方法(策略模式,也有人说代理模式)MyThread只需要提供run()方法,然后提供给Thread生产一个新的线程,之后只需Thread.start()即可,程序员不必考虑Thread内部到底调用什么东西运行线程的。
六,问题
线程经常遇见的问题就是数据共享,怎么做到数据共享?
例子(我想不同的线程每次都能读到一个共同的数t,然后输出,然后t–,直到t=0,就不输出了):
class MyThread8 implements Runnable {
private int t = 5;
@Override
public void run() {
for(int i = 0; i<10; i++) {
if(t > 0)
System.out.println( Thread.currentThread().getName() +": "+t--);
}
}
}
public class test4 {
public static void main(String g[]) {
MyThread8 m1 = new MyThread8();
new Thread(m1,"线程1").start();
new Thread(m1,"线程2").start();
}
}
结果:
这样就会有问题了:
class MyThread8 implements Runnable {
private int t = 5;
@Override
public void run() {
for(int i = 0; i<10; i++)
if(t > 0)
try {
Thread.currentThread().sleep(500);
System.out.println( Thread.currentThread().getName() +": "+t--);
} catch(Exception e) {}
}
}
public class test4 {
public static void main(String g[]) {
MyThread8 m1 = new MyThread8();
Thread t1 = new Thread(m1,"线程1");
Thread t2 = new Thread(m1,"线程2");
Thread t3 = new Thread(m1,"线程3");
t1.start();
t2.start();
t3.start();
}
}
在网络中,如果有延时,就会产出这样的错误,线程1还没来得及对t–,其他线程就使用了t
这就要使用同步了。