其实建立线程远远不止有3种方式,但这里只记录三种。html
一、经过继承Thread类来建立一个线程:
步骤1:定义一个继承Thread类的子类:
步骤2:构造子类的一个对象: Thread t1 = new Thread();
步骤3:启动线程: t1.start();
至此,一个线程就建立完成了。 java
二、经过实现Runnable接口来建立Thread线程:
步骤1:建立实现Runnable接口的类:
步骤2:建立一个类对象: Runnable runnable = new SomeRunnable();
步骤3:由Runnable建立一个Thread对象: Thread t2 = new Thread(runnable);
步骤4:启动线程: t2.start();
至此,一个线程就建立完成了。
三、与方法2相似,经过实现Callable接口来建立Thread线程。
步骤1:建立实现Callable接口的类;
步骤2:建立一个类对象: Callable callable = new SomeCallable();
步骤3:由Callable建立一个FutureTask对象: FutureTask ft= new FutureTask(callable);
步骤4:由FutureTask建立一个Thread对象: Thread oneThread = new Thread(ft);
步骤5:启动线程: oneThread.start();
至此,一个线程就建立完成了。 dom
可参考:推荐:http://www.importnew.com/25286.htmlide
package resource.java.ordinary.mul.thread; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * 线程Demo * * @author xiao */ public class TranditionThread { public static void main(String[] args) throws InterruptedException, ExecutionException { /* * 建立线程的方法一: */ Thread thread = new Thread() { @Override public void run() { // excuMethod(1); } }; thread.start(); /* * 建立线程方法二: */ Thread thread2 = new Thread(new Runnable() { @Override public void run() { // excuMethod(2); } }); thread2.start(); /* * 建立线程方法三: */ // FutureTask是一个包装器,它经过接受Callable来建立,它同时实现了 Future和Runnable接口。 FutureTask<String> ft = new FutureTask<String>(new Callable<String>() { @Override public String call() throws Exception { // excuMethod(3); System.out.println("hi~~ 此处有个新线程"); return "FutureTask 返回something"; } }); Thread t3 = new Thread(ft); t3.start(); String result = ft.get(); System.out.println(result);// 输出: FutureTask 返回something /* * 问题:此方法运行的是excuMethod(4)方法仍是excuMethod(5)方法?? */ new Thread(new Runnable() { @Override public void run() { // excuMethod(4); } }) { @Override public void run() { // excuMethod(5); } }.start(); } private static void excuMethod(int flag) { while (true) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(flag + " " + Thread.currentThread().getName()); } } }
对于上面问题的一个解答:this
答案:运行标识为5的线程。spa
思路:这个方法的结构是这样的:线程
new Thread( Runnable.run(){ // 标识为4的线程 }){ run(){ // 标识为5的线程 }}.start();
缘由:在Thread.class中,Thread是实现了Runnable接口的。在运行了Thread.start()方法后,先在子类中找run()方法,找到则用子类的方法,找不到在用父类的方法。在这题中,标识为5的线程所在的run()方法已经重写了父类的方法,因此最终运行的是excuMethod(5)方法。code
附:Callable与Future的使用实例htm
import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * Callable与Future的使用实例 * @author xiao * */ public class CallableAndFuture { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService threadPool = Executors.newSingleThreadExecutor(); /* * 获取某一线程的返回结果: * Callbale要采用ExecutorService的submit方提交,返回的future对象能够取消任务, 也能够获取线程的返回结果。 * Future取得的结果类型和Callable返回的结果类型必须一致,这是经过泛型来实现的。 */ Future<String> future = threadPool.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(2000); return "hello"; // 返回结果 } }); System.out.println("等待出结果"); System.out.println("拿到结果" + future.get());// 获取结果 /* * 获取一组线程的返回结果: * CompletionService用于提交一组Callable任务,其take方法放回已经完成的一个Callable任务对应的Future对象。 */ ExecutorService threadPool2 = Executors.newFixedThreadPool(10); CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool2); for (int i = 1; i <= 10; i++) { final int seq = i; // 运行每一个线程的任务 completionService.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { Thread.sleep(new Random().nextInt(5000)); return seq; } }); } // 获得全部线程运行的结果 for (int i = 0; i < 10; i++) { System.out.println(completionService.take().get()); } } }
一、synchronized的四种用法:对象
(1)修饰方法
(2)修饰一个代码块
(3)修饰一个静态方法
(4)修饰一个类
二、synchronized使用的demo
/** * 线程互斥:synchronized * @author xiao * */ public class TranditionThreadSynchronized { public static void main(String[] args) { new TranditionThreadSynchronized().init(); } public void init() { final Output ootput = new Output(); // 第一个线程 new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(1000); ootput.output2("xiao"); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); // 第二个线程 new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(1000); ootput.output2("hag"); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } class Output { public void output(String name) { int len = name.length(); // synchronized(XXX){}中,XXX表示的是要锁住的对象 // 此this指的是和output2中实现的效果同样,锁的是Output对象 synchronized (this) { for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } } public synchronized void output2(String name) { int len = name.length(); for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } } }
思考:若是须要在类Output中加入output3()方法(以下代码块所示),且output1()和output3()须要保持互斥,则须要作些什么?
public static synchronized void output3(String name) { int len = name.length(); for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); }
答案:须要作的事情有:
(1)内部类Output须要添加关键字static,以此变为外部类。
(2)将output1()中的synchronized (this)修改成synchronized (Output.class),使output1()方法中锁定的是Output类。
s