1.创建多线程
多线程3种创建方式
//第1种,创建Thread对象子类的对象
Thread t1 = new Thread(){
@Override
public void run() {
}
};
Thread t2 = new Thread(r);
//第2种,创建Runnable接口实现类的对象,作为Thread初始化参数
Runnable r = new Runnable() {
@Override
public void run() {
}
};
Thread t2 = new Thread(r);
//第3种,创建Callable接口实现类的对象,作为FutureTask初始化参数
//FutureTask的对象再作为Thread初始化参数
Callable callable = new Callable() {
@Override
public Object call() {
return null;
}
};
FutureTask f = new FutureTask(callable);
Thread t3 = new Thread(f);
//获取线程返回值,会一直堵塞到线程结束
f.get();
三种创建方式区别:
1.Runnable、Callable接口的方式:多个线程共享同一个target对象,适合多个相同线程来处理同一份资源。
2.继承Thread方式:编程简单,使用this即可获得当前对象,但无法继承其他父类。
2.多线程进阶
(1) 线程安全:线程的调度顺序不影响任何结果。
(2) 同步:人为的控制和调度,保证共享资源的多线程访问成为线程安全
(3) 同步的相关方法
synchronized(key) {} :对象同步锁
key.wait():线程进入等待,释放同步锁
key.notify():随机唤醒一个等待的线程,进入同步锁等待
key.notifyAll():唤醒所有等待的线程,进入同步锁等待
(4)Thread类的静态方法
Thread.sleep(time) :线程暂停一段时间,不释放资源。跟上面同步锁没啥关系。
Thread.yield() :运行状态回到就绪状态
Thread.currentThread():获取当前线程
Thread.interrupted():将当前线程的中断标志位复位(true→false)
(5)线程对象的方法
t.start():启动线程t
t.stop() :强制关闭线程t(不推荐使用,应该正常结束run方法)
t.join() :执行的线程要等待直到线程t运行结束(一般在main线程执行)
t.interrupt():将t线程的中断标志位改为true,从而在线程外控制内部run的执行逻辑
t.isInterrupted():获取t线程的中断标志位属性(true,false)
Runnable r = new Runnable() {
List key = new ArrayList();
Boolean flag = true;
@Override
public void run(){
synchronized(key) {
//第一个线程进入同步锁后进入等待,释放同步锁
if(flag) {
flag = false;
key.wait();
}
//第二个线程进同步锁,把第一个线程唤醒
key.notify();
}
}
};
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
3.多线程实例
(1)用三个线程,交替打印a,b,c
public class ThreadTest {
public String next = "a";
public static void main(String[] args) {
ThreadTest key = new ThreadTest();
new abcThread(key,"a","b").start();
new abcThread(key,"b","c").start();
new abcThread(key,"c","a").start();
}
}
class abcThread extends Thread{
private ThreadTest key;
private String now;
private String next;
public abcThread(ThreadTest key,String now,String next) {
this.key = key;
this.now = now;
this.next = next;
}
@Override
public void run() {
synchronized (key) {
try {
for(int i=0;i<10;) {
if(key.next.equals(now)) {
System.out.println(now);
key.next = next;
i++;
} else {
key.wait();
}
key.notifyAll();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
(2)多个线程售卖车票
public static void main(String[] args) throws InterruptedException {
Runnable run = new Runnable() {
List<String> ticket = Arrays.asList("a座","b座");
int i = 0;
@Override
public void run() {
String sell;
synchronized (ticket) {
sell = ticket.get(i);
i++;
}
System.out.println(Thread.currentThread().getName()+"卖出:"+sell);
}
};
Thread t1 = new Thread(run);
Thread t2 = new Thread(run);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("售票结束");
}