方法一
- 新建类如MyThread继承Thread类
- 重写run()方法
- 再通过new MyThread类来新建线程
- 通过start方法启动新线程
案例:
class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println(this.getName() + " " + i );
}
}
}
主类:
MyThread myThread1 = new MyThread("Thread-1");
MyThread myThread2 = new MyThread("Thread-2");
MyThread myThread3 = new MyThread("Thread-3");
myThread1.start();
myThread2.start();
myThread3.start();
常用方法
- static void sleep(T):让当前线程睡T毫秒
- static void yield():当前线程从运行变为就绪状态,重新争夺cpu
- void run():执行线程中run()方法(在当前线程中执行)
- void start():开启一个新的线程执行run()方法
- void setName():设置这个线程的名称
- String getName():获取当前线程的名称
- void interrupt():中断执行的子线程
- void join():等该线程执行完后,再执行当前线程
例:
当前主线程需等待t01,t02,t03线程执行完后再执行。
方法二
- 创建新类MyThread实现Runnable接口
- 实现接口中的run方法
- 创建MyThread对象,再新建Thread对象,将MyThread对象作为构造方法的参数传入Thread
- 通过start方法启动新的线程
案例:
class MyThread implements Runnable {
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName() + " " + i );
}
}
}
主类main方法中
MyThread myThread1 = new MyThread();
Thread myThread2 = new Thread(myThread1);
Thread myThread3 = new Thread(myThread1);
myThread2.start();
myThread3.start();
方法三
- 新建类MyThread实现Callable接口
- 实现接口中的call方法(有返回值)
- 创建MyThread对象,创建FutureTask对象将MyThread对象当作构造方法参数传入
- 创建Thread对象将FutureTask对象当构造方法参数传入(类似方法二第三步)
- 通过start方法启动新线程
- 通过FutureTask对象get方法获取返回结果
案例:
class MyThread implements Callable{
@Override
public Object call() throws Exception {
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName() + " " + i );
}
Thread.sleep(5000);
return 10+20;
}
}
main方法中:
FutureTask futureTask = new FutureTask(new MyThread());
Thread thread = new Thread(futureTask);
thread.start();
Object result = futureTask.get();
System.out.println("执行结果:"+result);
实际过程中会出现多线程相关问题,比如两个线程同时操控一个实例变量或共享变量,可能会存在数据不一致等问题。
编程模型
同步编程模型:线程一执行必须等待线程二执行结束,或相反,两个线程发生了等待关系。
异步编程模型:线程一和线程二同时执行。
解决方法
方法一
synchronized(锁的内容,通常为全局唯一例如类main.class){
执行的内容
}
方法二
通过Lock lock = new ReentrantLock()对象来上锁
lock.lock();//上锁
执行的内容
lock.unlock();//解锁
守护线程
一般是一个死循环,所有用户结束,守护线程也就结束。
开启方法
void setDaemon(true);
方法四
通过wait()和notify(),notifyAll()方法等待和唤醒线程。
线程池
多线程运行时,系统不断创建和销毁新的线程,成本非常高,使用线程池就是最好的选择。
创建
ExecutorService threadPoll = Executors.newCachedThreadPool();
threadPoll.execute(对象):线程池指派一个线程执行该对象run方法。
关闭线程池
threadPoll.shutdown();
多把锁
创建
CountDownLatch countDownLatch = new CountDownLatch(锁的数量);
锁数量减少
countDownLatch.countDown(); //锁的数量减一
等待
countDownLatch.await():等待子线程执行完再执行(锁的数量为0)
感谢观看——