线程的命名与取得
线程的命名:
- 通过构造方法在创建线程时设置线程名称
- 直接继承Thread类: public Thread (String name);
- Runable或者Callable接口实现多线程: public Thread (Runable target,String name);
- 在创建线程之后设置线程名称
- public final synchronized void setName(String name); //表示子类只能用
取得线程名称:
- public final String getName( );
如果想取得当前线程对象:
//在Thread类中提供有一个方法取得当前线程对象:
public static native Thread currentThread();
线程的命名与取得:
/线程的命名与取得
class Mythread1 implements Runnable
{
public void run()
{
System.out.println("线程名为:"+Thread.currentThread().getName());
}
}
public class SetGet
{
public static void main(String[] args) {
Mythread1 thread=new Mythread1();
new Thread(thread).start(); //没有设置线程名,默认从Thread-0开始
new Thread(thread).start();
new Thread(thread,"线程...").start(); //设置名字
}
}
public class SetGet
{
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()); //main
}
}
- 在线程启动后,可以由setName 修改线程名,子线程名称如果没有命名默认从Thread-0开始;
- 主方法是主线程,线程名为main;所有的线程都是通过主线程创建并启动的。每当使用了java命令去解释程序的时候,都表示启动了一个新的JVM进程。而主方法只是这个进程上的一个线程而已。
class Mythread1 implements Runnable
{
public void run()
{
System.out.println("线程名为:"+Thread.currentThread().getName());
}
}
public class SetGet
{
public static void main(String[] args) {
Mythread1 thread=new Mythread1();
thread.run(); //线程名为:main
new Thread(thread).start(); //线程名为:Thread-0
}
}
从上面结果可以看出,直接调用run方法,并没有启动一个线程,若想要启动一个线程必须调用Thread类的start方法。
线程休眠方法sleep( ) — 单位为毫秒
线程休眠指的是让线程暂缓执行,等到了预计时间再恢复执行。
线程暂缓状态改变:运行态(running)---->阻塞状态(blocked);
等到预计时间状态改变:阻塞态(blocked)—>就绪态(runable),到就绪态后等待系统调度。
线程休眠会立马交出cpu,CPU可以去执行其他的线程,但是并不会释放对象锁,也就是说假如这个线程持有对某个对象的锁,则即使调用sleep方法,其他线程也无法访问这个对象。
public static native void sleep(long millis) throws InterruptedException //注意,会抛异常
sleep是静态方法,通过类名来调用。
class Mythread2 implements Runnable
{
public void run()
{
for(int i=0;i<5;i++)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class SleepYield
{
public static void main(String[] args) {
Mythread2 thread=new Mythread2();
new Thread(thread).start();
new Thread(thread).start();
}
}
假如当线程Thread-0 休眠时,会立马交出cpu,CPU会执行另一个线程Thread-1。
2个线程谁先进入run方法是不一定的,要看cpu的调度。
线程让步yield( ):
线程让步是暂停执行当前的线程对象,并执行其他线程。
public static native void yield();
暂定时线程状态改变:由运行态(running)---->就绪态(runable),
因为它只是等待cpu何时来调度,这点和sleep不同。
yield()方法会让当前线程交出cpu,同样不会释放锁,但是yield()方法无法控制具体交出cpu的时间,并且yield()方法只能让拥有相同优先级的线程有获取cpu的机会。
//yield
class Mythread2 implements Runnable
{
public void run()
{
for(int i=0;i<5;i++)
{
Thread.yield();
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class SleepYield
{
public static void main(String[] args) {
Mythread2 thread=new Mythread2();
new Thread(thread).start();
new Thread(thread).start();
}
}
调用yield后并不知道什么时候交出cpu。
等待线程停止-----join( )方法
等待该线程终止。意思就是如果在主线程中一个线程调用该方法时就会让主线程休眠,让调用该方法的线程run方法先执行完毕之后在开始执行主线程。
/join方法
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
class Mythread2 implements Runnable
{
public void run()
{
System.out.print("主线程睡眠前的时间:");
printTime();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("主线程唤醒时间");
printTime();
}
private void printTime()
{
Date date=new Date();
DateFormat dateFormat=new SimpleDateFormat(("yyyy-MM-dd HH:mm:ss"));
String time=dateFormat.format(date);
System.out.println(time);
}
}
public class SleepYield
{
public static void main(String[] args) throws InterruptedException {
Mythread2 thread=new Mythread2();
Thread thread1=new Thread(thread,"子线程1");
thread1.start();
System.out.println(Thread.currentThread().getName());
thread1.join(); //子线程1调用join,会让主线程休眠,直至子线程1的run执行结束
System.out.println("代码结束"); //最后打印
}
}
子线程1在主线程中调用join方法,会让主线程休眠,直至子线程1的run方法结束。
join()方法线程状态改变: 从运行态到阻塞态,阻塞态到就绪态
调用sleep yield join三种方法线程状态改变: