
调用start方法执行
总结注意:线程开启不一定立即执行,由CPU调度执行
主线程和另一个线程交替执行
public class TestCallable implements Callable{ private String url; private String name; public TestCallable(String url,String name){ this.url = url; this.name = name; } public static void main(String[] args) throws ExecutionException, InterruptedException { TestCallable t1 = new TestCallable("https://profile.csdnimg.cn/0/0/E/1_m0_61453929","1.jpg"); TestCallable t2 = new TestCallable("https://img-blog.csdnimg.cn/20190927151026427.png?x-oss-process=image/resize,m_fixed,h_64,w_64","2.jpg"); TestCallable t3 = new TestCallable("https://img-blog.csdnimg.cn/20190918135101160.png?x-oss-process=image/resize,m_fixed,h_64,w_64","3.jpg"); //创建执行服务 ExecutorService ser = Executors.newFixedThreadPool(3); //提交执行 Future r1 = ser.submit(t1); Future r2 = ser.submit(t2); Future r3 = ser.submit(t3); //获取结果 Boolean rs1 = r1.get(); Boolean rs2 = r2.get(); Boolean rs3 = r3.get(); //关闭服务 ser.shutdown(); } @Override public Boolean call() { WebDownLoader webDownLoader = new WebDownLoader(); webDownLoader.downLoader(url,name); System.out.println("下载了文件名:" + name); return null; } } class WebDownLoader{ public void downLoader(String url,String name){ try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("IO异常,downLoader方法出现异常"); } } }
callable的好处:
public class StaticProxy {
public static void main(String[] args) {
WeddingCompany weddingCompany = new WeddingCompany(new You());
weddingCompany.HappyMarry();
}
}
interface Marry{
void HappyMarry();
}
class You implements Marry{
@Override
public void HappyMarry() {
System.out.println("秦老师要结婚了,非常开心");
}
}
class WeddingCompany implements Marry{
private Marry target;
public WeddingCompany(Marry target){
this.target = target;
}
@Override
public void HappyMarry() {
before();
this.target.HappyMarry();
after();
}
private void after(){
System.out.println("结婚后,收尾款");
}
private void before(){
System.out.println("结婚前,布置现场");
}
}
静态代理模式总结:
1.真实对象和代理对象都要实现同一个接口
2.代理对象要代理真实的角色
1.代理对象可以做很多真实对象做不了的事情
2.真实对象专注做自己的事情
1.lamdba表达式只能由一行代码的情况下才能简化为一行。如果由多行,那么就用代码块包裹
2.前提是接口为函数式接口
3.多个参数也可以去掉参数类型,要去掉都去掉,必须加上括号
可以模拟网络延迟、倒计时、显示当前时间
模拟网络延迟 倒计时 打印当前时间 线程礼让【yield】 线程插队【join】 守护线程【daemon】线程分为用户线程和守护线程
虚拟机必须确保用户线程执行完毕
虚拟机不用等待线程执行完毕
如:后台记录操作日志、监控内存、垃圾回收等
同步方法默认锁定的是this,当前这个类
同步块public class UnsafeBank {
public static void main(String[] args) {
//账户
Account account = new Account(100, "结婚基金");
Drawing you = new Drawing(account, 50, "你");
Drawing girlFriend = new Drawing(account, 100, "girlFriend");
you.start();
girlFriend.start();
}
}
class Account{
int money;//余额
String name;//卡名
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
//银行模拟取款
class Drawing extends Thread{
Account account;//账户
int drawingMoney;//取了多少钱
int nowMoney;//现在多少钱
public Drawing(Account account,int drawingMoney,String name){
super(name);
this.account =account;
this.drawingMoney = drawingMoney;
}
//synchronized 同步方法 默认锁的是this
@Override
public void run() {
//锁的对象是变化的量,保证安全
synchronized (account){
//判断有没有钱
if(account.money- drawingMoney < 0){
System.out.println(Thread.currentThread().getName()+"钱不够,取不了");
return;
}
//sleep可以放大问题的发生性
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//卡内余额 = 余额 - 你取的钱
account.money = account.money - drawingMoney;
//你手的钱
nowMoney = nowMoney + drawingMoney;
System.out.println(account.name + "余额为"+account.money);
//Thread.currentThread().getName() 等价于 this.getName()
System.out.println(this.getName() + "手里的钱" + nowMoney);
}
}
}
ReentrantLock lock = new ReentrantLock(); 可重用锁