注:每日专题系列均为本人为了梳理学习从各大博客收集整理,侵删
1、线程启动与执行
1、start(): 启动线程并执行相应的run()方法。
- 调用该方法会创建一个新的线程,而这个新的线程会执行Thread类中的run()方法。
- 一个线程不能重复start()
- 用start()来启动线程,实现了真正意义上的启动线程,此时会出现异步执行的效果。
package multithread;
class ThreadA extends Thread{
private int j;
public ThreadA(int num) {
j=num;
System.out.println("创建线程"+j);
}
public void run() {
for(int i=1;i<3;i++) {
try {
sleep((int)(1000*Math.random()));
}
catch(InterruptedException e){ }
System.out.println(Thread.currentThread().getName()+":计数"+i);
}
}
}
public class ByRun{
public static void main(String[] args) {
ThreadA a1=new ThreadA(1);
ThreadA a2=new ThreadA(2);
ThreadA a3=new ThreadA(3);
a1.start();
a2.start();
a3.start();
System.out.println("主方法main()运行结束!");
}
}
2、run(): 子线程要执行的代码放入run()方法。
- 调用此方法不会创建新的线程,而实直接在当前线程执行该方法。
- 用run()方法来启动线程,是同步执行,不会达到使用线程的意义。
package multithread;
class ThreadA extends Thread{
private int j;
public ThreadA(int num) {
j=num;
System.out.println("创建线程"+j);
}
public void run() {
for(int i=1;i<3;i++) {
try {
sleep((int)(1000*Math.random()));
}
catch(InterruptedException e){ }
System.out.println(Thread.currentThread().getName()+":计数"+i);
}
}
}
public class ByRun{
public static void main(String[] args) {
ThreadA a1=new ThreadA(1);
ThreadA a2=new ThreadA(2);
ThreadA a3=new ThreadA(3);
a1.run();
a2.run();
a3.run();
System.out.println("主方法main()运行结束!");
}
}
2、获取当前线程
1、Thread.currentThread(): 获取当前线程。
2、Thread.currentThread().getName(): 获取当前线程的名字。
3、Thread.currentThread().getId(): 获取当前线程唯一标识。
System.out.println(Thread.currentThread().getName());
3、线程休眠
线程休眠: 线程休眠是指让当前线程暂缓执行,等到规定休眠时间之后再恢复执行。线程休眠时会立即交出CPU,但不会释放锁。
线程休眠方法:sleep()
- sleep()流程:运行状态–>sleep()–>阻塞状态–>sleep()结束–>就绪状态–>系统调度–>运行状态。
- 由于线程处于就绪状态时,等待系统调度的时间是随机的,所以每次sleep()的时间是有差异的。
- sleep()会抛出InterruptedException异常,需要进行异常处理。
try {
sleep((int)(1000*Math.random()));
}
catch(InterruptedException e){ }
4、线程让步
线程让步: 线程让步是指暂停执行当前的线程对象,并执行其他线程。线程让步会交出当前CPU,但不一定立即交出。不会释放锁。
线程让步方法:yield()
- yield()方法无法控制具体交出CPU的时间,也无法保证其他线程一定获得CPU
- yield()方法只能让拥有相同优先级的线程有获取CPU的机会。
5、join()方法
join(): t.join方法会使主线程(当前运行的线程)进入等待状态等待t线程执行完毕之后才会被唤醒。
- join()流程:运行状态–>join()–>阻塞状态–>join()中断–>就绪状态–>系统调度–>运行状态。
- join()会抛出InterruptedException异常,需要进行异常处理。
6、wait()和notify()方法
wait(): 等待,如果线程执行了wait()方法,那么该线程会进入等待状态,等待状态下的线程必须要被其他线程调用notify()才能唤醒。
notify(): 唤醒,唤醒线程池等待线程的其中一个。
notify(): 唤醒线程池的所有等待线程。
注意:
- wait()方法和notify()方法必须要在同步代码块或同步函数中才能使用。
class Common{
private char ch;
//是否有商品
private boolean available=false;
//消费者获取商品方法
synchronized char get() {
while(available==false) {
//如果没有商品,则消费者先等待
try { wait(); }
catch(InterruptedException e) { }
}
available=false;
//唤醒消费者去消费
notify();
return ch;
}
//生产者生产商品方法
synchronized void put (char newch) {
while(available==true) {
//有商品时生产者等待消费者去消费
try { wait(); }
catch(InterruptedException e) { }
}
ch=newch;
available=true;
//唤醒生产者去生产
notify();
}
}
class Producer extends Thread{
private Common comm;
public Producer(Common thiscomm) {
comm=thiscomm;
}
public void run() {
char x;
for(x='a';x<='e';x++) {
System.out.println("生产的数据是:"+x);
comm.put(x);
}
}
}
class Consumer extends Thread{
private Common comm;
public Consumer(Common thiscomm) {
comm=thiscomm;
}
public void run() {
char y;
for(int i=0;i<5;i++) {
y=comm.get();
System.out.println("消费者得到的数据是:"+y);
}
}
}
public class Excercise11_5 {
public static void main(String[] args) {
Common comm=new Common();
Producer p=new Producer(comm);
Consumer con=new Consumer(comm);
p.start();
con.start();
}
}