多线程二常用方法
1.常用方法
1.1获取当前线程名
Thread.currentThread().getName()
1.2sleep睡眠方法:
static void sleep(long millis)
作用:让当前线程进入休眠,进入阻塞状态,放弃占有CPU时间片,让给其他线程使用
这行代码出现在A线程中,A线程就会进入休眠,出现在B线程,B线程就会进入休眠
public void test01(){
System.out.println(Thread.currentThread().getName());
//让当前线程进入休眠,睡眠5s
try {
Thread.sleep(1000*5);
} catch (InterruptedException e) {
e.printStackTrace();
}
//5秒后执行这里的代码
System.out.println("hello world");
}
public class Tests {
@Test
public void test01(){
MyThread myThread=new MyThread();
myThread.run();
try {
//这行代码并不会让线程myThread进入休眠
myThread.sleep(1000*5);//在执行的时候还是会转换成:Thread.sleep(1000*5)
//这行代码的作用是:让当前线程进入休眠,即main线程进入休眠
//这行代码出现在main方法中,main线程睡眠
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("hello world");
}
}
class MyThread extends Thread{
@Override
public void run() {
for(int i=0;i<1000;i++){
System.out.println(1);
}
}
}
1.3interrupt唤醒睡眠方法
sleep睡眠太久,如果希望半道上醒来,也就是怎么叫醒一个正在睡眠的线程
public class Tests {
@Test
public void test01(){
Thread thread=new Thread(new MyThread());
thread.setName("A");
thread.start();
try {
Thread.sleep(1000*5);
} catch (InterruptedException e) {
e.printStackTrace();
}
//终断t线程的睡眠(这种终断睡眠的方式依靠了java的异常处理机制)
thread.interrupt();//干扰
}
}
class MyThread implements Runnable{
//run()当中的异常不能throw只能try catch
//因为run()方法在父类中没有抛出任何异常,子类不能不能比父类抛出更宽泛的异常
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"---->begin");
try {
Thread.sleep(1000*60*60);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"----->end");
try {
doOther();//但是这里不能再run方法throws
} catch (Exception e) {
e.printStackTrace();
}
}
public void doOther()throws Exception{//这里是run方法外的其他方法,其他方法可以throws
}
}
1.4强行终止线程
public class Tests {
@Test
public void test01(){
Thread thread=new Thread(new MyThread());
thread.setName("A");
thread.start();
try {
Thread.sleep(1000*5);
} catch (InterruptedException e) {
e.printStackTrace();
}
//5秒之后强行终止t线程
thread.stop();//已过时,缺点:容易丢失数据 因为是直接将线程杀死
}
}
class MyThread implements Runnable{
@Override
public void run() {
for(int i=0;i<10;i++){
try {
System.out.println(i);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Tests {
@Test
public void test01(){
MyThread myThread=new MyThread();
Thread thread=new Thread(myThread);
thread.setName("A");
thread.start();
try {
Thread.sleep(1000*5);
} catch (InterruptedException e) {
e.printStackTrace();
}
//5秒之后强行终止t线程
myThread.run=false;//你想什么时候终止thread的执行,那么把标记修改为false就结束了
}
}
class MyThread implements Runnable{
boolean run=true;
@Override
public void run() {
for(int i=0;i<10;i++){
if(run){
try {
System.out.println(i);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("end");
}
}
}
}
1.5join合并线程
void join()
合并线程
class MyThread1 extends Thread{
public void doSome(){
MyThread2 t=new MyThread2();
t.join();//当前线程进入阻塞,t线程执行,直到t线程结束,当前线程才可以继续执行
}
}
class MyThread2 extends Thread{
}
1.6Object类中的wait和notify方法
wait方法和notify方法建立在synchronized线程同步的基础上
每个实力都拥有一个等待队列(等待队列是一个虚拟的概念,既不是实例中的字段,也不是用于获取正在实例上等待的线程的方法),他是在实例的wait方法执行之后停止操作的线程的队列
Object o=new Object();
//若要执行wait方法线程就必须持有锁
//wait方法会释放之前占有的o对象的锁
o.wait();//表示:让线程进入实例o的等待队列,让正在o对象上活动的线程进入等待状态,无期限等待,直到被唤醒为止。
//notify方法只会通知不会释放之前占有的锁
o.notify();//可以让正在o对象上等待的某个线程唤醒(要执行该方法,线程必须持有要调用的实例的锁),至于唤醒哪个线程并没有规定
o.notifyAll();//是唤醒o对象上处于等待的所有线程(也得持锁)
1.6.1生产者和消费者模式
生产者和消费者模式是为了专门解决某个特定需求
生产满了就不能消费就必须消费线程消费,消费完了就必须让生产线程进行生产
public class Tests {
@Test
public void test01(){
//创建一个共享的仓库对象
List list=new ArrayList<>();
Thread producerThread=new Thread(new Producer(list));//生产者线程
Thread consumerThread=new Thread(new Consumer(list));//消费者线程
producerThread.setName("生产者");
consumerThread.setName("消费者");
producerThread.start();
consumerThread.start();
}
}
class Producer implements Runnable{
private List list;
public Producer(List list) {
this.list = list;
}
@Override
public void run() {
while(true){
synchronized (list){
if(list.size()==3){
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(new Object());
System.out.println(Thread.currentThread().getName());
list.notifyAll();
}
}
}
}
class Consumer implements Runnable{
private List list;
public Consumer(List list) {
this.list = list;
}
@Override
public void run() {
synchronized (list){while (true){
if(list.size()==0){
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.remove(0);
System.out.println(Thread.currentThread().getName());
list.notifyAll();
}
}
}
}
与线程调度有关的方法
void setPriority(int new Priority) 设置线程的优先级
int getPriority()获取线程的优先级
最低优先级1
默认优先级5
最高优先级
System.out.println("最高优先级"+Thread.MAX_PRIORITY);//10
System.out.println("最低优先级"+Thread.MIN_PRIORITY);//1
System.out.println("默认优先级"+Thread.NORM_PRIORITY);//5
System.out.println(Thread.currentThread().getPriority());//5
static void yield() 让位方法
暂停当前正在执行的线程对象,并执行其他线程
不是阻塞方法,让当前线程让位,让当前线程从运行状态进入就绪状态