JAVA基础多线程(1)
一,多线程 (1)runnable的接口 (2)继承thread
首先的实现runnable的接口或者继承thread父类,并且重写run方法,run里写的就是运行的东西。
尽量用接口,因为毕竟一个类只能继承一个父类,接口灵活
1.继承实现
2.接口实现
//接口实现
public class PrintChar implements Runnable{
private int anInt;
private char aChar;
public void run() {
for (int i=0;i<anInt;i++) {
System.out.print(aChar);
}
运行的时候,java提供了一个Thread类,然后把写的简称类作为参数丢进去。
public class Main {
public static void main(String[] args) {
Thread t1=new Thread(new PrintChar(50,'a'));
Thread t2=new Thread(new PrintChar(40,'b'));
t1.start();
t2.start();
}
start并不是立即执行,而是让程序处于一个可运行的状态,具体的运行看cpu的心情。
二,Thread.yield()方法
这句话主要是cpu的执行权,看到这句话就直接让出了cup执行权,cpu就不理你了,干别的去了。
也就是说,PrintNum 每打印一次就会让出执行权,但什么时候又把执行权给他了就不知道了,也可能刚交出执行权但是CPU又给他了。
下边这个run是在上面的基础上,又写了一个PrintNum的类,重写的run方法。
public class PrintNum implements Runnable {
private int aNum;
public void run() {
for (int i=0;i<aNum;i++) {
System.out.print(i);
Thread.yield();
}
}
}
public class Main {
public static void main(String[] args) {
Thread t1=new Thread(new PrintChar(20,'a'));
Thread t2=new Thread(new PrintChar(20,'b'));
Thread t3=new Thread(new PrintNum(20));
t1.start();
t2.start();
t3.start();
}
}
三,Thread.sleep()方法
就是让线程睡一会,参数是毫秒。
下边这个程序的运行就是,到了线程3 之后会运行停顿,隔一下一输出。
public class PrintNum implements Runnable {
private long millis;
private int anInt;
public void run() {
for (int i=0;i<anInt;i++) {
System.out.print(i);
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
public class Main {
public static void main(String[] args) {
Thread t1=new Thread(new PrintChar(50,'a'));
Thread t3=new Thread(new PrintNum(200,10));
t3.start();
t1.start();
}
}
四,join()方法
就是在线程里插入一个别的线程
这个程序是在for线程里插入线程1,主函数里打印40遍“0”,在打10次的时候插入t1线程。
注意:我刚看结果的时候很疑惑,我明明先t1.start()应该是先输出“a”啊,怎么都是“0”先输出了?
其实,start只是让线程开启了可以运行的状态,至于线程什么时候运行,看cpu的心情。所以for里面的先输出了。下边的3个结果可以看出很随机。
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t1=new Thread(new PrintChar(10,'a'));
t1.start();
for(int i=0;i<40;i++){
System.out.print("0");
if (i==10){
t1.join();
}
}
}
五,setPriority()方法
设置优先级,有min,norm,max,但是也不是完全的先后,只是机会更大一些,毕竟cpu的随机性还是很大的。
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t1=new Thread(new PrintChar(10,'a'));
Thread t2=new Thread(new PrintChar(20,'b'));
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
}
}
六,interrupt()英文翻译是断点,但实际不是特别的贴切,应该叫“是否可以终止”。
在线程里实际是有close的,但是比较的粗暴,我们都知道close如果是运行的话,应该是在别的线程(t1)里突然的终止这个线程(t2),因为cpu是随机的,万一这时候人家t2还没运行完(重要的事务)就终止不就是出问题了吗。所以有了interrupt(),他不是直接把t2终止,而是把标识符从false打开到true(表示线程t1想让你终止),然后可以在t2线程里的某一处判断何时终止(是由此线程本身决定的)。
注意这个interrupt是对象的方法
主函数输出30个b,在输出5个之后就通知t1可以关了,而t1是一直在判断关闭的按钮是否开启,按钮开启了t1就终止。
public class PrintChar implements Runnable{
private int anInt;
private char aChar;
public void run() {
for (int i=0;i<anInt;i++) {
if (Thread.currentThread().isInterrupted()){break;}
System.out.print(aChar);
}
}
}
currentThread()返回的是当前的进程,isInterrupted()是对interrupt()返回参数的判断。
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t1=new Thread(new PrintChar(200,'a'));
t1.start();
for (int i=0;i<30;i++){
System.out.print("b");
if (i==5){
t1.interrupt();
}
}
}
}
下边是isInterrupted源码里对true or false(标志位) 情况的解释。
哈有一个interrupted(),注意这个是类的方法,
用处:他会接收标志位并输出,然后如果标志位是true(打开着)就把他变为false(关闭)
怎么用呢,别的线程想关闭你的话,会把标志位打开,如果你有不想结束进程,就可以用interrupted把他关闭
下边这个代码:实际在别的线程里已经用interrupt把标志位改成了true,这时interrupted()返回了true,然后把true改成了false,
currentthread返回当前的线程,isInterrupted()对interrupt()返回参数的判断,所以打印的是false。
public class PrintChar implements Runnable{
private int anInt;
private char aChar;
public void run() {
for (int i=0;i<anInt;i++) {
if (Thread.currentThread().isInterrupted()){
System.out.println(Thread.interrupted());
}
System.out.print(aChar);
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t1=new Thread(new PrintChar(50,'a'));
t1.start();
for (int i=0;i<30;i++){
System.out.print("b");
if (i==5){
t1.interrupt();
}
}
}
}
输出结果:
小结:
interrupt(),这是对象的方法,不是直接把线程终止,而是把标识符从false打开到true,然后可以在此线程里的某一处判断何时终止(是由此线程本身决定的)。
interrupted(),这个是类的方法,他会接收标志位并输出,然后如果标志位是true(打开着)就把他变为false(关闭)
currentthread返回当前的线程
isInterrupted()是对interrupt()返回参数的判断。