目录
Java创建线程两种方式的调用优先级
首先依旧是老样子,先把源码和运行结果贴出来,再来解释原因
public class One {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("runnable:"+Thread.currentThread().getName());
}
}){
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread:"+Thread.currentThread().getName());
}
};
thread.start();
}
}
结果可以看的出:控制台打印的是子类里run方法
首先必须知道不管是Thread调用子类还是Runnable接口
实现线程运行都是重写run方法体
先来看下run方法是实现
target !=null 的条件下,调用target.run,这里的target 是 Runnable
Runnable是传参进来的,而Thread是子类构造进来的
显然这需要巩固一个知识点:当子类重写了父类的函数,那么子类的对象如果调用该函数,一定调用的是重写过后的函数。可以通过super关键字进行父类的重写函数的调用。
也就是说先调用的是Thread子类run方法
子类把run方法重写后,原Thread中的run方法也就不会执行
所以Runnable中的run方法没执行
Java线程使用
public class ThreadTest {
public static void main(String[] args) {
final TaskInfo taskInfo = new TaskInfo();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
taskInfo.sub(i);
}
}
}).start();
for (int i = 1; i <= 50; i++) {
taskInfo.main(i);
}
}
//建议实际操作的内容单独封装
//更面向对象
//synchronized(obj)中的对象obj 必须obj.wait()中的obj必须是同一对象
//不然等待的就可能是伪等待
static class TaskInfo {
private boolean falg = true;
public synchronized void main(int n) {
while (!falg) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 1; i <= 100; i++) {
System.out.println("第" + n + "次主线程:" + i + Thread.currentThread().getName());
}
falg = false;
this.notify();
}
public synchronized void sub(int n) {
while (falg) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 1; i <= 10; i++) {
System.out.println("第" + n + "次子线程:" + i + Thread.currentThread().getName());
}
falg = true;
this.notify();
}
}
}
当前线程范围存储
import java.util.Random;
public class ThreadScopeLocal {
public static void main(String[] args) {
for (int i = 1; i <= 2; i++) {
new Thread(
new Runnable() {
@Override
public void run() {
int random = new Random().nextInt();
MyThreadScopeData.getThreadInstance().setName(""+random);
MyThreadScopeData.getThreadInstance().setAge(random);
new A().get();
new B().get();
}
}).start();
}
}
static class A {
public void get() {
System.out.println(Thread.currentThread().getName() + "A Name" + MyThreadScopeData.getThreadInstance().getName());
System.out.println(Thread.currentThread().getName() + "A Age" + MyThreadScopeData.getThreadInstance().getAge());
}
}
static class B {
public void get() {
System.out.println(Thread.currentThread().getName() + "B Name" + MyThreadScopeData.getThreadInstance().getName());
System.out.println(Thread.currentThread().getName() + "B Age" + MyThreadScopeData.getThreadInstance().getAge());
}
}
}
//使用饥饿模式 封装的当前线程范围 存取参数
class MyThreadScopeData {
private MyThreadScopeData() {
}
public static MyThreadScopeData getThreadInstance() {
MyThreadScopeData instance = map.get();
if (instance == null) {
instance = new MyThreadScopeData();
map.set(instance);
}
return instance;
}
private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
atomic是java线程并发包
线程池Executors
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolTest {
public static void main(String[] argas) {
//ExecutorService threadPool = Executors.newFixedThreadPool(3);//启动3个线程完成任务
//Start 3 threads to complete the task
//ExecutorService threadPool = Executors.newCachedThreadPool();//缓存线程完成任务,不限制线程数量
//Cache threads complete tasks without limiting the number of threads
ExecutorService threadPool = Executors.newSingleThreadExecutor();//单个线程死掉后会有其他单个线程替补
//When a single thread dies,it will be repalced by another single thread
for(int i=1;i<=10;i++) {
final int task = i;
threadPool.execute(new Runnable() {
@Override
public void run() {
for (int j = 1; j <=10; j++)
System.out.println(Thread.currentThread().getName() + "任务" + task + "的循环" + j + "次");
}
});
}
System.out.println("all of 10 tasks have committed!");
threadPool.shutdown();//执行完后提交执行任务
//Submit the task after execution
threadPool.shutdownNow();//未执行完提交执行任务
//Submit execution task not completed
//固定10秒炸
/**
* @ corePoolSize 基本线程数
* @ l 任务多久时间后执行一次
* @ TimeUnit 时间单位
*/
Executors.newScheduledThreadPool(3).schedule(new Runnable() {
@Override
public void run() {
System.out.println("bombing!");
}
},10, TimeUnit.SECONDS);
/**
* @ corePoolSize 基本线程数
* @ l 任务多久时间后执行一次
* @ l1 每隔多久时间执行一次
* @ TimeUnit 时间单位
*/
Executors.newScheduledThreadPool(3).scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("bombing!");
}
},6,2, TimeUnit.SECONDS);
}
}
等待线程运行结果
import java.util.Random;
import java.util.concurrent.*;
public class CallableAndFuture {
public static void main(String[] args) {
//等待线程运行结果
ExecutorService threadExecutor = Executors.newCachedThreadPool();
Future<String> future =
threadExecutor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(2000);
return "hello";
}
});
System.out.println("等待结果");
try {
System.out.println("拿到结果:"+future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//等待线程运行结果
ExecutorService threadPool = Executors.newFixedThreadPool(10);
ExecutorCompletionService<String> completionService = new ExecutorCompletionService<String>(threadPool);
for(int i=1;i<=10;i++) {
final int sub = i;
completionService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(new Random().nextInt(5000));
return "线程"+Thread.currentThread().getName()+"运行了"+sub;
}
});
}
for(int i=1;i<=10;i++) {
try {
System.out.println(completionService.take().get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
Lock锁的妙用
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class LockTest {
private static Map<String, Object> cache = new HashMap<String, Object>();
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
public static void main(String[] args) {
//普通锁
// Lock lock = new ReentrantLock();
// lock.lock();
//要同步排斥的内容
// lock.unlock();
}
//制作缓存案列
public Object getDate(String key) {
rwl.readLock().lock();// 读锁可以同时多个线程读
Object value = null;
try {
value = cache.get(key);
if (value == null) {
rwl.readLock().unlock();
rwl.writeLock().lock();//写锁一次只能一个线程写
try {
if(value == null){
value = "hello";
cache.put(key, value);
}
}finally {
rwl.writeLock().unlock();
}
rwl.readLock().lock();
}
} finally {
rwl.readLock().unlock();
}
return value;
}
}