public class MyTest {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
new Thread(myRunnable).start();
while (true){
if (myRunnable.getFlag()) {
System.out.println("进来了");
break;
}
}
}
//要说内存可见性问题,得先了解一下我们JVM的内存模型
//Java内存模型规定了所有的变量都存储在主内存中。每条线程中还有自己的工作内存,
//线程的工作内存中保存了被该线程所使用到的变量(这些变量是从主内存中拷贝而来)。
//线程对变量的所有操作(读取,赋值)都必须在工作内存中进行。
//不同线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。
//volatile 只是解决内存可见性的问题,但是他不能保证原子性,原子性:就是不可再分割性
}
class MyRunnable implements Runnable{
volatile boolean flag=false;
public boolean getFlag() {
return flag;
}
@Override
public void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag=true;
System.out.println("flag的值是"+getFlag());
}
}
1.3 多线程(CAS 算法)
* CAS 算法
(1)CAS (Compare-And-Swap) 是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的
一种特殊指令,用于管理对共享数据的并发访问
(2) CAS 是一种无锁的非阻塞算法的实现。
* CAS 包含了 3 个操作数:
(1) 需要读写的内存值 V
(2) 进行比较的值 A
(3) 拟写入的新值 B
当且仅当 V 的值等于 A 时, CAS 通过原子方式用新值 B 来更新 V 的值,否则不会执行任何操作
jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁。
* java.util.concurrent.atomic 包下提供了一些原子操作的常用类:
AtomicBoolean 、 AtomicInteger 、 AtomicLong 、 AtomicReference
AtomicIntegerArray 、 AtomicLongArray
AtomicMarkableReference
AtomicReferenceArray
例子:
public class MyTest2 {
public static void main(String[] args) {
//i++ 不是一个原子性操作
//CAS 算法:比较并交换
//是一种硬件支持
IRunnable iRunnable = new IRunnable();
for (int i = 0; i < 10; i++) {
new Thread(iRunnable).start();
}
}
}
class IRunnable implements Runnable{
// int i=0;
//把普通变量换成原子变量,
AtomicInteger num=new AtomicInteger(1);
@Override
public void run() {
while (true){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":" + num.getAndIncrement());
}
}
}
public class MyTest2 {
public static void main(String[] args) {
//线程池:是一个容器,装有一定线程对象的容器
//为什么要线程池
//从JDK5开始,Java内置支持线程池
//B:
//内置线程池的使用概述
//JDK5新增了一个Executors工厂类来产生线程池,有如下几个方法
//ExecutorService 线程池
// public static ExecutorService newCachedThreadPool ():根据任务的数量来创建线程对应的线程个数
ExecutorService executorService = Executors.newCachedThreadPool();
MyRunnable myRunnable = new MyRunnable();
executorService.submit(myRunnable);
executorService.submit(new MyRunnable());
executorService.submit(new MyRunnable());
executorService.submit(new MyRunnable());
executorService.submit(new MyRunnable());
executorService.submit(new MyRunnable());
executorService.submit(new MyRunnable());
//关闭线程池
executorService.shutdown();
}
}
public class MyTest3 {
public static void main(String[] args) {
//这个线程里面,提前创建三个线程对象
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(new MyRunnable());
executorService.submit(new MyRunnable());
executorService.submit(new MyRunnable());
executorService.submit(new MyRunnable());
executorService.submit(new MyRunnable());
executorService.submit(new MyRunnable());
executorService.shutdown();
}
}
1.7 多线程(定时器的概述和使用)
* 定时器概述
定时器是一个应用十分广泛的线程工具,可用于调度多个定时任务以后台线程的方式执行。
在Java中,可以通过Timer和TimerTask类来实现定义调度的功能。
* Timer和TimerTask
Timer:
public Timer()
public void schedule(TimerTask task, long delay):
public void schedule(TimerTask task,long delay,long period);
public void schedule(TimerTask task, Date time):
public void schedule(TimerTask task, Date firstTime, long period):
TimerTask:定时任务
public abstract void run()
public boolean cancel()
开发中
Quartz是一个完全由java编写的开源调度框架。
例子:
public class MyTest3 {
public static void main(String[] args) throws ParseException {
//定时删除文件夹
Timer timer = new Timer();
String dateStr = "2019-07-30 14:42:00";
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr);
MyTimerTask myTimerTask = new MyTimerTask(timer);
timer.schedule(myTimerTask,date);
}
}
public class MyTimerTask extends TimerTask {
Timer timer;
public MyTimerTask(Timer timer) {
this.timer=timer;
}
@Override
public void run() {
File file = new File("E:\\测试图片");
delFolder(file);
timer.cancel();//取消定时器
}
private void delFolder(File file) {
File[] files = file.listFiles();
for (File f : files) {
if(f.isFile()){
f.delete();
}else{
delFolder(f);
}
}
file.delete();
}
}