有关java5以后的线程
程序员文章站
2022-03-20 15:54:15
创建线程的方式 方式一 继承于Thread类 方式一与方式二比较推荐使用方式二,方式二实现的方式没有类的单继承性的局限性,实现的方式更适合来处理多个线程有共享数据的情况。 测试Thread中的常用方法: 创建线程的方式三: 实现Callable接口。 JDK 5.0新增 方式四 使用线程池 ......
创建线程的方式
方式一
继承于thread类
/** * 多线程的创建,方式一:继承于thread类 * 1. 创建一个继承于thread类的子类 * 2. 重写thread类的run() --> 将此线程执行的操作声明在run()中 * 3. 创建thread类的子类的对象 * 4. 通过此对象调用start() * <p> * 例子:遍历100以内的所有的偶数 * * @author shkstart * @create 2019-02-13 上午 11:46 */ //1. 创建一个继承于thread类的子类 class mythread extends thread { //2. 重写thread类的run() @override public void run() { for (int i = 0; i < 100; i++) { if(i % 2 == 0){ system.out.println(thread.currentthread().getname() + ":" + i); } } } } public class threadtest { public static void main(string[] args) { //3. 创建thread类的子类的对象 mythread t1 = new mythread(); //4.通过此对象调用start():①启动当前线程 ② 调用当前线程的run() t1.start(); //问题一:我们不能通过直接调用run()的方式启动线程。 // t1.run(); //问题二:再启动一个线程,遍历100以内的偶数。不可以还让已经start()的线程去执行。会报illegalthreadstateexception // t1.start(); //我们需要重新创建一个线程的对象 mythread t2 = new mythread(); t2.start(); //如下操作仍然是在main线程中执行的。 for (int i = 0; i < 100; i++) { if(i % 2 == 0){ system.out.println(thread.currentthread().getname() + ":" + i + "***********main()************"); } } } }
方式二
实现runnable接口
/** * 创建多线程的方式二:实现runnable接口 * 1. 创建一个实现了runnable接口的类 * 2. 实现类去实现runnable中的抽象方法:run() * 3. 创建实现类的对象 * 4. 将此对象作为参数传递到thread类的构造器中,创建thread类的对象 * 5. 通过thread类的对象调用start() * * * 比较创建线程的两种方式。 * 开发中:优先选择:实现runnable接口的方式 * 原因:1. 实现的方式没有类的单继承性的局限性 * 2. 实现的方式更适合来处理多个线程有共享数据的情况。 * * 联系:public class thread implements runnable * 相同点:两种方式都需要重写run(),将线程要执行的逻辑声明在run()中。 * * @author shkstart * @create 2019-02-13 下午 4:34 */ //1. 创建一个实现了runnable接口的类 class mthread implements runnable{ //2. 实现类去实现runnable中的抽象方法:run() @override public void run() { for (int i = 0; i < 100; i++) { if(i % 2 == 0){ system.out.println(thread.currentthread().getname() + ":" + i); } } } } public class threadtest1 { public static void main(string[] args) { //3. 创建实现类的对象 mthread mthread = new mthread(); //4. 将此对象作为参数传递到thread类的构造器中,创建thread类的对象 thread t1 = new thread(mthread); t1.setname("线程1"); //5. 通过thread类的对象调用start():① 启动线程 ②调用当前线程的run()-->调用了runnable类型的target的run() t1.start(); //再启动一个线程,遍历100以内的偶数 thread t2 = new thread(mthread); t2.setname("线程2"); t2.start(); } }
方式一与方式二比较推荐使用方式二,方式二实现的方式没有类的单继承性的局限性,实现的方式更适合来处理多个线程有共享数据的情况。
测试thread中的常用方法:
/** * 测试thread中的常用方法: * 1. start():启动当前线程;调用当前线程的run() * 2. run(): 通常需要重写thread类中的此方法,将创建的线程要执行的操作声明在此方法中 * 3. currentthread():静态方法,返回执行当前代码的线程 * 4. getname():获取当前线程的名字 * 5. setname():设置当前线程的名字 * 6. yield():释放当前cpu的执行权 * 7. join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a才 * 结束阻塞状态。 * 8. stop():已过时。当执行此方法时,强制结束当前线程。 * 9. sleep(long millitime):让当前线程“睡眠”指定的millitime毫秒。在指定的millitime毫秒时间内,当前 * 线程是阻塞状态。 * 10. isalive():判断当前线程是否存活 * * * 线程的优先级: * 1. * max_priority:10 * min _priority:1 * norm_priority:5 -->默认优先级 * 2.如何获取和设置当前线程的优先级: * getpriority():获取线程的优先级 * setpriority(int p):设置线程的优先级 * * 说明:高优先级的线程要抢占低优先级线程cpu的执行权。但是只是从概率上讲,高优先级的线程高概率的情况下 * 被执行。并不意味着只有当高优先级的线程执行完以后,低优先级的线程才执行。 * * * @author shkstart * @create 2019-02-13 下午 2:26 */ class hellothread extends thread{ @override public void run() { for (int i = 0; i < 100; i++) { if(i % 2 == 0){ // try { // sleep(10); // } catch (interruptedexception e) { // e.printstacktrace(); // } system.out.println(thread.currentthread().getname() + ":" + thread.currentthread().getpriority() + ":" + i); } // if(i % 20 == 0){ // yield(); // } } } public hellothread(string name){ super(name); } } public class threadmethodtest { public static void main(string[] args) { hellothread h1 = new hellothread("thread:1"); // h1.setname("线程一"); //设置分线程的优先级 h1.setpriority(thread.max_priority); h1.start(); //给主线程命名 thread.currentthread().setname("主线程"); thread.currentthread().setpriority(thread.min_priority); for (int i = 0; i < 100; i++) { if(i % 2 == 0){ system.out.println(thread.currentthread().getname() + ":" + thread.currentthread().getpriority() + ":" + i); } // if(i == 20){ // try { // h1.join(); // } catch (interruptedexception e) { // e.printstacktrace(); // } // } } // system.out.println(h1.isalive()); } }
创建线程的方式三:
实现callable接口。 --- jdk 5.0新增
import java.util.concurrent.callable; import java.util.concurrent.executionexception; import java.util.concurrent.futuretask; /** * 创建线程的方式三:实现callable接口。 --- jdk 5.0新增 * * * 如何理解实现callable接口的方式创建多线程比实现runnable接口创建多线程方式强大? * 1. call()可以有返回值的。 * 2. call()可以抛出异常,被外面的操作捕获,获取异常的信息 * 3. callable是支持泛型的 * * @author shkstart * @create 2019-02-15 下午 6:01 */ //1.创建一个实现callable的实现类 class numthread implements callable{ //2.实现call方法,将此线程需要执行的操作声明在call()中 @override public object call() throws exception { int sum = 0; for (int i = 1; i <= 100; i++) { if(i % 2 == 0){ system.out.println(i); sum += i; } } return sum; } } public class threadnew { public static void main(string[] args) { //3.创建callable接口实现类的对象 numthread numthread = new numthread(); //4.将此callable接口实现类的对象作为传递到futuretask构造器中,创建futuretask的对象 futuretask futuretask = new futuretask(numthread); //5.将futuretask的对象作为参数传递到thread类的构造器中,创建thread对象,并调用start() new thread(futuretask).start(); try { //6.获取callable中call方法的返回值 //get()返回值即为futuretask构造器参数callable实现类重写的call()的返回值。 object sum = futuretask.get(); system.out.println("总和为:" + sum); } catch (interruptedexception e) { e.printstacktrace(); } catch (executionexception e) { e.printstacktrace(); } } }
方式四
使用线程池
/** * 创建线程的方式四:使用线程池 * * 好处: * 1.提高响应速度(减少了创建新线程的时间) * 2.降低资源消耗(重复利用线程池中线程,不需要每次都创建) * 3.便于线程管理 * corepoolsize:核心池的大小 * maximumpoolsize:最大线程数 * keepalivetime:线程没有任务时最多保持多长时间后会终止 * * * 面试题:创建多线程有几种方式?四种! * @author shkstart * @create 2019-02-15 下午 6:30 */ class numberthread implements runnable{ @override public void run() { for(int i = 0;i <= 100;i++){ if(i % 2 == 0){ system.out.println(thread.currentthread().getname() + ": " + i); } } } } class numberthread1 implements runnable{ @override public void run() { for(int i = 0;i <= 100;i++){ if(i % 2 != 0){ system.out.println(thread.currentthread().getname() + ": " + i); } } } } public class threadpool { public static void main(string[] args) { //1. 提供指定线程数量的线程池 executorservice service = executors.newfixedthreadpool(10); threadpoolexecutor service1 = (threadpoolexecutor) service; //设置线程池的属性 // system.out.println(service.getclass()); // service1.setcorepoolsize(15); // service1.setkeepalivetime(); //2.执行指定的线程的操作。需要提供实现runnable接口或callable接口实现类的对象 service.execute(new numberthread());//适合适用于runnable service.execute(new numberthread1());//适合适用于runnable // service.submit(callable callable);//适合使用于callable //3.关闭连接池 service.shutdown(); } }
上一篇: Go实现各类限流的方法