多线程的常用操作方法
线程名称
创建线程的时候设置名称
public Thread(Runnable target,String name)
设置线程的名称
public final synchronized void setName(String name)
获取线程的名称
public final String getName()
获得当前线程对象
public static native Thread currentThread();
public class TestThread {
public static void main(String[] args) {
MyThread myThread1 = new MyThread();
new Thread(myThread1).start();//开启线程,不设置名称
new Thread (myThread1,"my1").start();//设置线程名称,并开启线程
}
}
class MyThread implements Runnable{
public void run(){
for (int i = 0;i<3;i++){
System.out.println("当前线程"+Thread.currentThread().getName()+" i="+i);//获取当前线程的名称
}
}
}
线程休眠(sleep方法)
线程休眠就是让线程暂停一段时间,直到到达规定的时间停止暂停,开始执行。
值得注意的是,线程休眠是交出CPU,让CPU执行其他任务,但是不会释放对象锁,其他线程不会访问当前锁的对象。
休眠的时间是以毫秒作为单位。
使线程到阻塞状态。
public static native void sleep(long milis) throws InterruptedException
public class TestSleep {
public static void main(String[] args) {
Runnable runnable =new Runnable (){
public void run (){
for(int i = 0;i<5;i++){
try {
Thread.sleep(1000);//线程休眠
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" i="+i);
}
}
};
new Thread(runnable,"Thread-1").start();
new Thread(runnable,"Thread-2").start();
new Thread(runnable,"Thread-3").start();
}
}
在这里,三个线程不是同时休眠的。
总体是并发执行。
线程让步(yield方法)
交出CPU的执行权限,让CPU执行其他的线程,但是他不能控制具体交出CPU的时间,只能是相同优先级的线程有获得CPU执行的机会。
不会释放锁
不会让线程进入阻塞状态,而是回到就绪状态。
public class TestYield {
public static void main(String[] args) {
Runnable runnable =new Runnable(){
public void run (){
for (int i= 0;i<5;i++){
Thread.yield();//交出CPU的时间不可控,当前线程回到就绪状态。
System.out.println(Thread.currentThread().getName()+" i="+i);
}
}
};
new Thread(runnable,"Thread-1").start();
new Thread(runnable,"Thread-2").start();
new Thread(runnable,"Thread-3").start();
}
}
join()方法
等待线程终止,如果主线程调用了该方法,就会使主线程休眠,让调用该方法的线程中的run()方法执行结束,才执行主线程。
public class TestJoin {
public static void main(String[] args) {
//main线程开始执行
System.out.println(Thread.currentThread().getName()+"开始执行");
//自定义线程
Thread myJoin = new Thread(new MyJoin(),"Thread-myJoin");
myJoin.start();
try {
myJoin.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行结束");
}
}
class MyJoin implements Runnable {
public void run(){
System.out.println(Thread.currentThread().getName()+"开始执行");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"结束执行");
}
}
线程停止
有三种方法可以使线程停止
1.设置标记位,使线程正常退出
2.使用stop()方法,强制是线程退出,但是该方法不太安全,已经废弃
3.使用Thread类中的interrupt()方法,使线程退出
方法一
public class TestStop1 {
public static void main(String[] args) {
MyStop myStop1 = new MyStop();
myStop1.setName("Thread-Stop-1");
myStop1.start();
MyStop myStop2 = new MyStop();
myStop2.setName("Thread-Stop-2");
myStop2.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
myStop2.setFlag(false);
}
}
class MyStop extends Thread{
//判断线程是否停止
private volatile boolean flag=true;
public void run() {
int i=0;
while (flag){
i++;
System.out.println(Thread.currentThread().getName()+" i="+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
方法二
public class TestStop2 {
public static void main(String[] args) {
Thread thread=new Thread(new Runnable () {
public void run() {
int i = 0;
while (true){
i++;
System.out.println(Thread.currentThread().getName()+" i="+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"Thread-Stop-1");
thread.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.stop();
}
}
使用stop使线程强制退出,该方法不太安全已经被废弃了
为什么不安全?
因为stop会解除所有的锁,当一个线程对象调用stop()方法是,这个线程对象的线程就会立即停止,就会产生不完整的数据。
方法三
public class TestStop3 {
public static void main(String[] args) throws InterruptedException {
Runnable runnable =new Runnable() {
@Override
public void run() {
int i=0;
while(true){
i++;
boolean flag = Thread.currentThread().isInterrupted();
if(flag){
break;
}
System.out.println(Thread.currentThread().getName()+" i="+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
boolean bool =Thread.currentThread().isInterrupted();
System.out.println(bool);
return;
}
}
}
};
Thread thread = new Thread(runnable, "Thread-stop-3");
thread.start();
Thread.sleep(5000);
thread.interrupt();
}
}
interrupt方法只是给线程设置一个中断标志,将中断标志设置为true,并根据线程状态来决定是否抛出异常。
线程优先级
线程的优先级越高,线程有可能优先执行
设置优先级
public final void setPriority(int newPriority)
获取优先级
public final int getPriority()
对于优先级设置的内容可以使用Thread类的几个常量来决定
- 最高优先级:public final static int MAX_PRIORITY = 10;
- 中等优先级:public final static int NORM_PRIORITY = 5;
- 最低优先级:public final static int MIN_PRIORITY = 1;
public class TestPriority {
public static void main(String[] args) {
Runnable runnable=new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
System.out.println(Thread.currentThread().getPriority());
Thread son=new Thread (()->{
System.out.println(Thread.currentThread().getName());
System.out.println(Thread.currentThread().getPriority());
},"Thread-son");
son.start();
}
};
Thread threadParent=new Thread(runnable,"Thread-Parent");
threadParent.setPriority(9);
threadParent.start();
}
}
线程具有继承性,不如在线程A里面执行线程B,那么线程A和B的优先级是一样的
守护线程
public class TestDaemon {
public static void main(String[] args) {
//新建一个守护线程
Thread threadA=new Thread(new MyRunnable(),"Thread-A");
threadA.setDaemon(true);
threadA.start();
//创建一个用户线程
Thread threadB=new Thread(new MyRunnable(),"Thread-B");
threadB.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadB.interrupt();
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
int i=0;
try {
while(true){
i++;
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+" i=" +i+" 是否是守护线程:"+Thread.currentThread().isDaemon());
}
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(Thread.currentThread().getName()+"发生中断");
}
}
}
设置守护线程时,一定要在开启该线程之前设置。