本文共 5269 字,大约阅读时间需要 17 分钟。
一个【程序】至少有一个【进程】,一个【进程】至少有一个【线程】。
1.启动当前线程2.调用当前线程的重写的run方法(在主线程中生成子线程,有两条线程)调用start方法以后,一条路径代表一个线程,同时执行两线程时,因为时间片的轮换,所以执行过程随机分配,且【一个线程对象只能调用一次start方法】。run方法的作用:在主线程中调用以后,直接在主线程一条线程中执行了该线程中run的方法。(调用线程中的run方法,只调用run方法,并不新开线程)
public class ThreadDemo { public static void main(String[] args) { Window t1 = new Window(); Window t2 = new Window(); Window t3 = new Window(); t1.setName("售票口1"); t2.setName("售票口2"); t3.setName("售票口3"); // start 的方式启动,是非并发的,start是开启线程,再调用方法;一条路径代表一个线程 t1.start(); t2.start(); t3.start(); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); }}class Window extends Thread { //将其加载在类的静态区,所有线程共享该静态变量 private static int ticket = 100; @Override public void run() { while (true) { synchronized (Window.class) { if (ticket > 0) { try { sleep(100L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getName() + "当前售出第" + ticket + "张票"); ticket--; } else { break; } } } }}
比较创建线程的两种方式:
开发中,优先选择实现Runnable接口的方式 原因 1:实现的方式没有类的单继承性的局限性 2:实现的方式更适合用来处理多个线程有共享数据的情况public class ThreadRunnable { /** * 1.创建一个实现了Runable接口的类 * 2.实现类去实现Runnable中的抽象方法:run() * 3.创建实现类的对象 * 4.将此对象作为参数传递到Thread类中的构造器中,创建Thread类的对象 * 5.通过Thread类的对象调用start() * */ private static int ticket = 100; public static void main(String[] args) { Runnable runnable = new Runnable() { @Override public void run() { while (true) { synchronized (ThreadRunnable.class){ if (ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "当前售出第" + ticket + "张票"); ticket--; } else { break; } } } } }; //虽然有三个线程,但是只有一个窗口类实现的Runnable方法,由于三个线程共用一个window对象,所以自动共用100张票 Thread t1 = new Thread(runnable); Thread t2 = new Thread(runnable); Thread t3 = new Thread(runnable); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); }}
callable 方式相对于继承Thread和实现Runable接口的方式,callable支持返回值
import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;/** * callable实现新建线程的步骤: * 1.创建一个实现callable的实现类 * 2.实现call方法,将此线程需要执行的操作声明在call()中 * 3.创建callable实现类的对象 * 4.将callable接口实现类的对象作为传递到FutureTask的构造器中,创建FutureTask的对象 * 5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start方法启动(通过FutureTask的对象调用方法get获取线程中的call的返回值) */public class ThreadCallable { private static int sum = 0; public static void main(String[] args) { // 就一个线程,非多线程 // ①、实现callable接口,覆写 call 方法 Callablecallable = new Callable () { @Override public Integer call() throws Exception { for (int i = 0; i <= 100; i++) { Thread.sleep(100); if (i % 2 == 0) { System.out.println(Thread.currentThread().getName() + "----> :" + i); sum += i; } } return sum; } }; // ②、将 callable 实现类对象传递到 FutureTask 构造器中 FutureTask integerFutureTask = new FutureTask<>(callable); // ③、将 FutureTask 传递到 Thread 的构造器中 Thread thread = new Thread(integerFutureTask); thread.setName("线程123"); thread.start(); System.out.println("------------------------------------------------------"); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>> 线程未执行完成,先执行后面的代码"); System.out.println("------------------------------------------------------"); try { // 获取返回值 System.out.println("integerFutureTask.get() = " + integerFutureTask.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }}
尽量使用线程池创建对象:
// 创建一个线程池名称工厂ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();// 手动创建一个线程池ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());// 单个线程池开始执行singleThreadPool.execute(()-> System.out.println(Thread.currentThread().getName()));// 单个线程池关闭singleThreadPool.shutdown();
转载地址:http://mexxi.baihongyu.com/