1、线程的创建方式
- extends Thread
- implements Runnable
- implements Callable 通过Callable和Future创建线程
2、实现方式
public class thread {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//直接继承Thread
ThreadEx threadEx=new ThreadEx();
threadEx.start();
//实现Runnable接口
Thread threadRunnable=new Thread(new ThreadRunnable());
threadRunnable.start();
//实现Callable接口
Callable callable=new ThradCallAble();
FutureTask futureTask=new FutureTask(callable);
Thread threadCallable=new Thread(futureTask);
threadCallable.start();
//线程里面的返回值,可以抛出异常
System.out.println(futureTask.get());
}
}
class ThreadEx extends Thread{
@Override
public void run() {
System.out.println("Thread extend Thread");
}
}
class ThreadRunnable implements Runnable{
@Override
public void run() {
System.out.println("Thread implements Runnable");
}
}
class ThradCallAble implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("Thread implements Callable");
return "return Call";
}
}
3、三种实现方式的区别
https://www.cnblogs.com/yangdy/p/5274455.html
-
实现Runnable接口比继承Thread类所具有的优势
适合多个相同的程序代码的线程去处理同一个资源
可以避免java中的单继承的限制
增加程序的健壮性,代码可以被多个线程共享,代码和数据独立 -
Callable比Runnable接口所具有的优势
可以抛出异常
可以接收线程里面的返回值
4、线程同步
public class thread {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//实现Runnable接口
ThreadRunnable runnable=new ThreadRunnable();
Thread threadRunnable1=new Thread(runnable,"线程1");
Thread threadRunnable2=new Thread(runnable,"线程2");
Thread threadRunnable3=new Thread(runnable,"线程3");
threadRunnable1.start();
threadRunnable2.start();
threadRunnable3.start();
}
}
class ThreadRunnable implements Runnable{
private int flag=20;
@Override
public void run() {
option();
}
public void option(){
while (true){
if(flag<1){
break;
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread implements Runnable:"+Thread.currentThread().getName()+":"+flag--);
}
}
}
实现多线程共享flag数据
- private volatile int flag=20; 共享数据添加volatile关键字
- synchronized(this){
System.out.println(“Thread implements Runnable:”+Thread.currentThread().getName()+":"+flag–);
}
使用synchronized数据块锁 - 方法上加锁 public synchronized void option();
这种方法不可取,锁的位置太大,影响效率,而且只有一个线程对flag进行了–操作
5、sleep和wait的区别
对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。
sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
在调用sleep()方法的过程中,线程不会释放对象锁。
而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备
获取对象锁进入运行状态。
https://www.cnblogs.com/hongten/p/hongten_java_sleep_wait.html