线程
一、线程的概念 进程是正在执行的程序。在操作系统中进程是进行系统资源分配、调度和管理的最小单位,进程在执行过程中拥有独立的内存单元。比如:Windows采用进程作为最小隔离单位,每个进程有属于自己的数据段、程序段 ,并且与别的进程没有任何关系。 一个或更多的线程构成了一个进程(操作系统是以进程为单位的,而进程是以线程为单位的,进程中必须有一个主线程)。 为了解决进程调度资源的浪费,为了能够共享资源,出现了线程。线程是CPU调度和分派的基本单位,它可与同属一个进程的其他的线程共享进程所拥有的全部资源,多个线程共享内存,从而极大地提高了程序的运行效率。 如果一个进程没有了,那么线程肯定会消失,如果线程消失了,但是进程未必会消失。而且所有线程都是在进程的基础之上并同时运行。 二、创建线程的两种方式及区别 ?1 继承Thread类 ? ? 1.1 示例代码
AA ( System.out.println("world" Thread.sleep(2000 }
main(String[] args) AA a1 = a1.start();
( System.out.println("hello" Thread.sleep(2000);
}
?2 实现Runnable接口 ? ? 2.1?定义一个类,实现Runnable接口,并覆盖 run()方法,在这个方法里是我们希望这个线程运行的代码。 ? ? 2.2?创建一个这个新类的对象。 ? ? 2.3?创建一个Thread类的对象,用刚才的Runnable对象作为构造函数参数。 ? ? 2.4?调用Thread对象的start()方法来启动线程。 ? ? 2.5?示例代码
AA ( System.out.println("world" Thread.sleep(2000 }
main(String[] args) AA a1 = AA();
Thread t1 = Thread(a1);
t1.start();
( System.out.println("hello" Thread.sleep(2000);
}
3、实现Runnable接口与继承Thread的区别 ? ?3.1 实现Runnable 接口比继承 Thread 类有如下的明显优点:? ? ? ? (1)、适合多个相同程序代码的线程去处理同一个资源。 ? ? ? ? (2)、可以避免由于单继承局限所带来的影响。 ? ? ? ? (3)、增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。 ? ?3.2 Thread更加简单易用 三、线程的生命周期 多线程在操作过程也有一个固定的操作状态,任何一个线程都具有五种状态:创建、就绪、运行、阻塞、终止 创建状态:准备好的一个多线程的对象 就绪状态:调用了start()方法,等待cpu调度 运行状态:执行run()方法。
终止状态:线程执行完毕,不再使用。 四、线程同步加锁解决资源竟态问题 ? ? ? ?1. 竞态的概念 ? ? ? ? ? ?1.1 多个线程调用同一资源就会产生竞争状态(竞态) ? ? ? ? ? ?1.2?访问的同一资源,我们称之为临界资源 ? ? ? ? ? ?1.3?访问临界资源的代码,我们称之为临界区 ? ? ? ? ? ?1.4?如果两个线程同时取得数据,将会造成流水号重复 ? ? ? ? ? ?1.5 示例代码 CThread i=1;
( Thread.sleep(1000 }
}
out.println(CThread.i);
Thread.sleep(1000 }
CThread.i++;
(CThread.i==100) main(String[] args)
Thread t1= Thread t2=
}
? ? ? 2.?解决方法是利用同步加锁 ? ? ? ? ? ?2.1?多个线程访问同一资源,线程之间相互协调的功能,叫线程同步。也就是说在同一个时间段内只能有一个线程进行,其他线程要等待此线程完毕之后才可以继续执行。 ? ? ? ? ? ?2.2?在临界资源上放置同步块synchronized()可以解决这个问题 ? ? ? ? ? ?2.3?线程执行到synchronized()代码块时首先看看有没有锁定,如果没有锁定,则获得锁,如果已经锁定,则需要等待,线程离开synchronized()代码块的时候释放锁。 ? ? ? ? ? ?2.4?这一切的过程由系统任意给定的一个对象来监视,这个对象放入synchronized块的()中 ? ? ? ? ? ?2.5 示例代码
java.lang.System.*
CThread i = 1;
Object j = Object();
( (j)
{
Thread.sleep(1000 } }
out.println(CThread.i);
Thread.sleep(1000 } CThread.i++;
(CThread.i == 100 }
main(String[] args) Thread t1 = Thread t2 =
}
五、线程安全类 ? ? ? ?1?把一个类中的方法标志为synchronized,我们称之为该类线程安全,多个线程访问同一个对象的内部数据将会采用线程同步
dd
i = 1
( ( Thread.sleep(1000 }
}
out.println(i);
Thread.sleep(1000 }
i++;
(i == 100
CThread
dd j = dd();
main(String[] args)
Thread t1 = Thread t2 =
}
六、Notify()与notifyall()区别 ? ? ? ?1. 使用notify(),通知第一个等待线程,所有排队的线程按先后顺序执行。? ? ? ?2. notifyall()通知所有的等待线程,那么优先级别高线程就先执行。 七、yeild()与sleep()的区别
? ? ? ?3. Thread.sleep()调用会给较低优先级线程一个运行的机会。 ? ? ? ?4. Thread.yield()方法只会给相同优先级线程一个执行的机会。 八、join() ?在一个线程A里面加入另一个线程B运行,等待B线程运行完以后再运行A线程 九、wait ?notify 的应用生产者消费者问题
Object monitor = Object();
String flowNo = ;
Customer
out.println("now the thread:" + Thread.currentThread().getName() + " get lock" out.println("now the thread:" + Thread.currentThread().getName() + " is waiting" Product.monitor.wait();
}
Producter
out.println("now the thread:" + Thread.currentThread().getName() + " get lock"
Scanner sc = Product.flowNo = out.println("now notify all thread to work" Product.monitor.notifyAll();
main(String[] args) Customer t1 = Customer("customer" Producter p1 = Producter("producter" }
十、线程池以及使用线程池的好处 ? ? ? ?1、多线程运行时间,系统不断的启动和关闭新线程,成本非常高? ? ? ?2、使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。
CThread i=1;
Object j= Object();
( (j)
{
Thread.sleep(1000 }
}
out.println(CThread.i);
Thread.sleep(1000 }
CThread.i++;
(CThread.i==100) }
main(String[] args)
ExecutorService server=Executors.newFixedThreadPool(2);
server.submit( CThread());
server.submit(
server.shutdown();
}
十一、定时调度 ? ? ? ? ? 1. 定时调度的本质是一个线程,只是系统控制了这个线程运行的时间与频率
aa
out.println("1 "
main(String[] args)
Timer t1 = t1.schedule( aa(),1000);
in.read();
t1.cancel();
}
? ? ? ? ? ?2.?schedule到达某一个时间点开始执行
aa
out.println("1 "
main(String[] args)
Timer t1 = aa aa1 = Calendar c1 = c1.add(Calendar.SECOND,5 c1.set(2017,10,8,00,29,10 t1.schedule(aa1,c1.getTime());
}
? ? ? ? ? ?3.?到达某一个时间点,再按照频率执行
aa
out.println("1 "
main(String[] args)
t1.schedule(aa1,c1.getTime(),1000);
}
? ? ? ? ? ?4.?延误时间间隔之后执行
aa
out.println("1 "
main(String[] args)
t1.schedule(aa1,2000,1000);
}
? ? ? ? ? ?5.?固定频率
aa
out.println("1 "
main(String[] args)
t1.scheduleAtFixedRate(aa1,5000);
}
? ? ? ? ? ?6.?多定时器,多任务
aa
out.println("1 "
bb
out.println("2 "
cc
SimpleDateFormat sf = SimpleDateFormat("yyy.MM.dd hh:mm:ss" String curDate = sf.format( Date( out.println(curDate + " 3 "
main(String[] args) Timer t1 = aa aa1 = bb bb1 = t1.scheduleAtFixedRate(aa1,2000);
t1.scheduleAtFixedRate(bb1,1000);
Timer t2 = cc cc1 = t2.scheduleAtFixedRate(cc1,3000);
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |