线程:Thread
Thread thread = new Thread();
线程类里面代码如下:
@Override
public void run() {
if (target != null) {
target.run();
}
}
得知启动线程可以重写run方法,或者给target赋值,使用构造器调用init()赋值,即重写target(Runable)的run方法.
代码:
public static void main(String[] args) {
// 第一个线程
Thread thread = new Thread() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
};
thread.start();
// 第二个线程
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
});
thread2.start();
一个容易搞混的代码
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Runnable中的run!");
}
}) {
public void run() {
System.out.println("Thread中的run!");
}
}.start();
//结果是:Thread中的run!
定时器Timer
System.out.println("主线程:"+Thread.currentThread().getName());
new Timer().schedule(new TimerTask() {
@Override
public void run() {
System.out.println("定时器中的线程:"+Thread.currentThread().getName());
System.out.println("执行");
}
}, 10000[,1000]);
for(int i=10;i>=0;) {
System.out.println(i--);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
结果:主线程:main
10…1
定时器中的线程:Timer-0
执行
0
定时器迭代调用
class MyTimerTask extends TimerTask {
@Override
public void run() {
System.out.println("执行");
new Timer().schedule(new MyTimerTask(), 1000);
}
}
new Timer().schedule(new MyTimerTask(), 1000);
拓展:每天晚上三点收邮件(schedule可以写绝对时间)
线程安全
同步快
值得注意的是,可以用字符串常量来对不同的对象的方法加同步锁
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
new SynchronizedTest().test();
}
}
private void test() {
Test1 test1 = new Test1();
new Thread(new Runnable() {
@Override
public void run() {
new Test1().show("111111111111");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
new Test1().show("0000000000000");
}
}).start();
}
class Test1 {
public void show(String name) {
synchronized("123") {
int len = name.length();
for (int i = 0; i < len; System.out.print(name.charAt(i++)));
System.out.println();
}
}
}
线程的互斥与同步通信
方法中的synchronized是对this进行同步的
静态方法是对XXX.class进行同步的,也就是说对xxx.class加锁的对象也可以和xxx类的静态方法同步.
锁是放在资源内部的
一个经典题目
public class ThreadQuestion {
//题目:主线程循环10次,子线程循环20次,然后主线程循环10次,再子线程...依次类推50次
//思路:创建一个类来专门维护这个对象,首先定义两个互斥的方法(保证循环的过程中安全),
//然后设置一个旗帜来决定顺序,进行wait和notify操作
public static void main(String[] args) {
//创建对象方便加锁
QuestionService qs = new QuestionService();
new Thread(new Runnable() {
@Override
public void run() {
//子线程运行50次
for(int i=0;i<50;i++) {
qs.sub();
}
}
}).start();
//主线程也是50次
for(int i=0;i<50;i++) {
qs.main();
}
}
}
class QuestionService{
//旗帜
private boolean shouldSub = false;
public synchronized void main() {
//如果不该主线程就等待
//while防治伪唤醒
while(shouldSub) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//执行循环
for(int i=0;i<10;System.out.print(i++));
System.out.println();
//改变旗帜状态
shouldSub = true;
//打醒该类的wait的方法?
this.notify();
}
public synchronized void sub() {
//如果不该子线程就等待
while(!shouldSub) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i=0;i<20;System.out.print(i++));
System.out.println();
//改变状态
shouldSub = false;
//执行其他线程
this.notify();
}
}