在多线程操作中,有一些常用的方法可以直接供我们使用,这篇博客主要总结一下这些基本操作。
1:线程的命名与取得
因为多线程的运行状态我们无法确定,所以在对多线程的操作必须有一个明确标识出线程对象的信息,这个信息往往通过名称来描述。在Thread类中,提供了一系列的相关方法。
方法名称 | 类型 | 描述 | |
1 | public Thread(Runnable target, String name); | 构造方法 | 在创建线程的同时设置名称 |
2 | public final synchronized void setName(String name); | 普通方法 | 设置线程名称 |
3 | public final String getName(); | 普通方法 | 取得线程名字 |
/**
* Returns a reference to the currently executing thread object.
*
* @return the currently executing thread.
*/
public static native Thread currentThread();
currentThread()方法可以返回代码段正在被哪个线程调用的信息,下面我通过一个示例进行说明。
public class Main{
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
}
}
我们可以发现,man方法被一个名为main的线程所调用。我们现在再验证一种情况
class My_Thread extends Thread{
My_Thread(){
System.out.println("构造方法:"+Thread.currentThread().getName());
}
@Override
public void run() {
System.out.println("run方法:"+Thread.currentThread().getName());
}
}
public class Main{
public static void main(String[] args){
Thread New_Thread = new My_Thread();
Thread New_Thread2 = new My_Thread();
New_Thread.start();
New_Thread2.start();
}
}
我们可以发现:My_Thread类的构造方法被main线程所调用,例子中创建了两个新的线程,两个线程的run方法被名称为Thrad-0和Thread-1的线程所调用。那么我们可以的出一个结论:如果没有设置线程的名字,则会被自动分配一个线程名字。除此之外,还需要注意的是,线程名字尽量不要设置重复,并且在线程运行的过程中不要修改。
另外,我们也可以注意到:主方法本来就是一个线程,所有的线程都是通过主线程创建并启动的。
关于线程的常用方法,大致可以用一张图来描述
sleep()方法:
它的作用是在指定的毫秒数内让当前正在执行的进程"休眠"(暂停执行)。这个正在执行的进程指的是this.currentThread()返回的线程对象。但是需要注意的是,sleep方法不会解锁,所以说如果当前线程持有某个对象的锁,即使调用了sleep方法,其他的线程也无法访问这个对象。
public static native void sleep(long millis) throws InterruptedException;
关于这个方法的一些细节,我举一个例子来说明下
class My_Thread extends Thread{//继承于Thread类
My_Thread(){
}
@Override
public void run() {
for(int i = 0;i<1000;i++) {
try {
Thread.sleep(1500);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}
public class Main{
public static void main(String[] args){
Thread New_Thread = new My_Thread();
new Thread(New_Thread).start();
new Thread(New_Thread).start();
new Thread(New_Thread).start();
}
}
来看一下结果
我们可以看出来这三个线程是并发执行的,而且,还有一点需要注意,这三个线程不是同时休眠的。
还有一种和sleep方法类似的方法
yield():线程让步:该方法会放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间,但是yield方法不能控制具体的交出CPU的时间,而且,它只能让拥有相同优先级的线程有获取CPU执行时间的机会。
另外,yield方法不会让线程进入阻塞状态,而是让线程重回就绪状态,它只需要等待重新获取CPU执行时间,这一点和sleep方法是有区别的。
class My_Thread extends Thread{
@Override
public void run() {
long Begin_Tie = System.currentTimeMillis();
int count = 0;
for(int i = 0;i<1000000;i++){
//Thread.yield();
count = count + (i + i);
}
long End_Time = System.currentTimeMillis();
System.out.println("用时:"+(End_Time - Begin_Tie)+"毫秒");
}
}
public class Main{
public static void main(String[] args){
Thread New_Thread = new My_Thread();
new Thread(New_Thread).start();
}
}
yield方法有一个弊端:它会导致执行速度变慢,因为它会突然把CPU让给其他资源,这样会导致速度变慢。
去掉注释后:
不去掉注释:
这就很能说明问题了。
关于多线程的操作我分成几个部分总结,先总结到这里。