- 如果执行以下代码结果会输出什么,并说明思路
/*new 了一个对象(子对象)继承了Thread对象(父对象),在子对象里重写了父类的run()方法;然后父对象里面扔了个Runnable进去,父对象中的run()方法就是最初那个带有 if 判断的run()方法。现在执行start()后,肯定先在子类中找run()方法,找到了,父类的run()方法自然就被干掉了,所以会打印出:Thread run。*/
//会优先执行子类重写的方法
public static void main(String[] args) {
new Thread(() -> System.out.println("runnable run")) {
@Override
public void run() {
System.out.println("Thread run");
}
}.start();
}
- 写两个线程,一个线程打印1~52,另一个线程打印A~Z,打印顺序是12A34B...5152Z;
代码语言:javascript复制第一种方法:各个对象在线程体内,通过验证如果数值对象在循环到偶数时sleep一下等待字母输出,此方法需要设置线程优先值,一般数值大于字母两个优先值时比较稳定。
//2、写两个线程,一个线程打印1~52,另一个线程打印A~Z,打印顺序是12A34B...5152Z;
// String[] str = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
// int[] num = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52}
public class ThreadDemo2 {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
int[] num = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52};
for (int i = 0; i < num.length; i ){
// 要先输出再等待,如果先等待再输出可能会造成字母先于数字
System.out.println(num[i]);
if(num[i]%2 != 1){ //是偶数
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t1.setPriority(3);// 设置线程优先级(重点)
t1.start();
// 不同的线程优先值结果不同,只要t1>t2两个优先值则受影响概率较小
Thread t2 = new Thread(()->{
String[] str = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
for (int i = 0; i < str.length; i ){
// 要先输出再等待,如果先等待再输出可能会造成数字先于字母
System.out.println(str[i]);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t2.setPriority(1);// 设置线程优先级(重点)
t2.start();
}
}
代码语言:javascript复制第二种方法:各个对象在线程体内,通过验证标志位来判断是否该自己输出,如果是数字执行两位也就是偶数的时候更改标志位让字母输出,字母输出完直接更改标志位,while循环的时候一定设置休眠,要不可能会卡死,这种方法比上面的方法稳定,通过标志位的判断输出保证了他们的输出顺序。
//2、写两个线程,一个线程打印1~52,另一个线程打印A~Z,打印顺序是12A34B...5152Z;
// String[] str = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
// int[] num = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52}
public class ThreadDemo2 {
private static boolean flag = true; // 定义一个标志位
public static void main(String[] args) {
new Thread(()->{
int[] num = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52};
for (int i = 0; i < num.length; i ){
// 如果flag是false就等待字母输出,while循环的时候定义一下休眠,不要让他一直去查这个值,要不它会卡掉
while (flag == false){
try {
Thread.sleep(10);// 每次循环休眠0.01s
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(num[i]);// 输出值
if(num[i]%2 != 1){ //是偶数,该字母输出了
flag = false;// 定义flag为false,告诉字母你该输出了
}
}
}).start();
new Thread(()->{
String[] str = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
for (int i = 0; i < str.length; i ){
// 如果flag是true就等待数字输出,while循环的时候定义一下休眠,不要让他一直去查这个值
while (flag == true){
try {
Thread.sleep(10);// 每次循环休眠0.01s
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(str[i]);// 输出字母
flag = true;// 因为字母每次输出一次所以输出完标志位直接定义为true
}
}).start();
}
}
- 子线程循环10次,主线程循环100次,然后子线程循环10次,主线程循环100次,这样循环50次;
代码语言:javascript复制由线程创建一个循环50次的for,在里面先创建子现场输出1-10,在子现场执行的时候为了保证输出顺序让主线程休眠0.01s以保证子线程输出完主线程才输出
//3、子线程循环10次,主线程循环100次,然后子线程循环10次,主线程循环100次,这样循环50次;
class ThreadDemo3 {
// 由线程创建一个循环50次的for,在里面先创建子现场输出1-10,在子现场执行的时候为了保证输出顺序让主线程休眠0.01s以保证子线程输出完主线程才输出
public static void main(String[] args){
for (int i = 0; i < 50; i ) {
new Thread(()->{
for (int j = 0; j < 10; j ) {
System.out.println(Thread.currentThread().getName() " -- " j);
}
}).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int j = 0; j < 100; j ) {
System.out.println(Thread.currentThread().getName() " -- " j);
}
}
}
}
- 现在有T1、T2、T3三个线程,保证T2在T1执行完后执行,T3在T2执行完后执行。
1.设置线程优先级保证让t1,t2,t3按顺序执行,但是它不能保证t1执行完后执行t2而是并行状态
代码语言:javascript复制// 现在有T1、T2、T3三个线程,保证T2在T1执行完后执行,T3在T2执行完后执行。
class ThreadDemo4 {
public static void main(String[] args){
Thread t1 = new Thread(()->System.out.println("1"));
Thread t2 = new Thread(()->System.out.println("2"));
Thread t3 = new Thread(()->System.out.println("3"));
// 1.设置线程优先级保证让t1,t2,t3按顺序执行,但是它不能保证t1执行完后执行t2而是并行状态
t1.setPriority(8);
t2.setPriority(5);
t3.setPriority(1);
t1.start();
t2.start();
t3.start();
}
}
代码语言:javascript复制2.使用while死循环监控现场数量,如果t1执行完毕再执行t2,t2执行完执行t3,但是使用线程数量定义是不准确的,所以使用线程状态
代码语言:javascript复制public static void main(String[] args){
Thread t1 = new Thread(()->System.out.println("1"));
Thread t2 = new Thread(()->System.out.println("2"));
Thread t3 = new Thread(()->System.out.println("3"));
// 2.使用while死循环监控现场数量,如果t1执行完毕再执行t2,t2执行完执行t3,但是使用线程数量定义是不准确的,所以使用线程状态
t1.start();
// 定义死循环检查线程数量
while (true){
// 如果数量为1则t1线程已经执行完毕执行t2并退出循环
if (Thread.activeCount() == 1){
t2.start();
break;
}
}
// t3同理,等待t2
while (true){
if (Thread.activeCount() == 1){
t3.start();
break;
}
}
}
代码语言:javascript复制3.使用while死循环监控需要等待线程的状态
代码语言:javascript复制public static void main(String[] args){
Thread t1 = new Thread(()->System.out.println("1"));
Thread t2 = new Thread(()->System.out.println("2"));
Thread t3 = new Thread(()->System.out.println("3"));
// 3.使用while死循环监控需要等待线程的状态
t1.start();
// 定义死循环检查线程状态
while (true){
// 如果t1执行结束,执行t2并退出循环
if (t1.getState().equals(Thread.State.TERMINATED)){
t2.start();
break;
}
}
// t3同理,等待t2
while (true){
if (t2.getState().equals(Thread.State.TERMINATED)){
t3.start();
break;
}
}
}