Java线程操作
一、获取线程相关信息
//获取线程信息的相关方法
Thread main = Thread.currentThread();
//线程名字
String name = main.getName();
System.out.println("name:"+name);
//获取线程id
long id = main.getId();
System.out.println("id:"+id);
//线程优先级
int priority = main.getPriority();
System.out.println(priority);
//是否处于活动状态
boolean isAlive = main.isAlive();
System.out.println("isAlive:"+isAlive);
//是否为守护线程
boolean isDaemon = main.isDaemon();
System.out.println("isDaemon:"+isDaemon);
//是否被中断
boolean isInterrupted = main.isInterrupted();
System.out.println("isInterrupted:"+isInterrupted);
二、创建一个线程(主要分两种)
2.1、继承Thread并重写run方法
public class CreateThread1 {
public static void main(String[] args){
MyThread mt = new MyThread();
mt.start();
}
}
class MyThread extends Thread{
@Override
public void run() {
for(int i=0;i<10;++i){
System.out.println("我是MyThread的run方法");
}
}
}
2.2、实现Runnable接口单独定义线程任务
第一种创建线程的方式存在两个设计上的不足:
- 继承冲突,由于java是单继承的,这就导致一个类如果希望是线程,同时又需要扩展另一个类的功能时,由于不能同时继承这两个类,导致继承冲突。
- 继承线程需要重写run方法来定义线程任务,这就导致线程与任务定义在一起有一个强耦合关系,不利于线程重用。
public class CreateThread2 {
public static void main(String[] args){
MyRunnable mr = new MyRunnable();
Thread t = new Thread(mr);
t.start();
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
for(int i=0; i<10; ++i){
System.out.println("我是MyRunnable的run方法");
}
}
}
2.3、主要是通过匿名类来完成上面两种线程创建方式
Thread t1 = new Thread(){
@Override
public void run() {
for(int i=0; i<10; ++i){
System.out.println("继承Thread创建");
}
}
};
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0; i<10; ++i){
System.out.println("实现Runnable创建");
}
}
});
t1.start();
t2.start();
三、常用方法
3.1、后台线程(守护线程)
Thread parentThread = new Thread(){
@Override
public void run() {
for(int i=0; i<10; ++i){
System.out.println(i+":parentThread...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("parentThread over");
}
};
Thread childThread = new Thread(){
@Override
public void run() {
for(int i=0; i<100; ++i){
System.out.println(i+":childThread...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("childThread over");
}
};
//将childThread设置为后台线程(守护线程)
childThread.setDaemon(true);
parentThread.start();
childThread.start();
3.2 、线程优先级
线程对于线程调度的工作是不可控制的。线程只能被动的被分配CPU时间,不能主动获取。线程只能被动的被分配CPU时间,不能主动获取。改变线程优先级可以最大程序改善线程获取CPU的几率。理论上线程优先级越高的线程获取CPU时间片的次数越多。
Thread max = new Thread(){
@Override
public void run() {
for(int i=0;i<10000;++i){
System.out.println("max");
}
}
};
Thread min = new Thread(){
@Override
public void run(){
for(int i=0;i<10000;++i){
System.out.println("min");
}
}
};
//设置优先级
min.setPriority(1);
max.setPriority(10);
min.start();
max.start();
3.3、线程睡眠
static void sleep(long ms)
该方法会导致运行当前方法的线程进入阻塞状态指定的毫秒值。当超时后,线程会自动回到Runnable状态,等待再次分配CPU时间并发运行。
//模拟电子表功能
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
while(true){
System.out.println(sdf.format(new Date()));
Thread.sleep(1000);
}
四、线程同步
3.1、join实现同步
private static boolean isFinish = false;
public static void main(String[] args) throws RuntimeException {
final Thread download = new Thread(){
public void run(){
System.out.println("down:开始下载图片...");
for(int i=0;i<=100;i++){
System.out.println("down:"+i+"%");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("down:图片下载完毕!");
isFinish = true;
}
};
Thread show = new Thread(){
public void run(){
System.out.println("show:开始显示图片...");
try{
//等待该线程结束
download.join();
}catch(InterruptedException e){
e.printStackTrace();
}
if(!isFinish){
throw new RuntimeException("图片没有下载完毕!");
}
System.out.println("show:显示图片完毕!");
}
};
download.start();
show.start();
}