------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ----
来源:互联网 发布:软件板块指数 编辑:程序博客网 时间:2024/04/25 04:56
创建线程的两种方式:
继承Thread类,覆盖.run()方法,在子类创建对象时,线程就建立了。.start()方法启动线程。如果不启动,直接.run()方法,这时run()方法的内容还是主线程运行的。多线程根本没有启动。
实现Runnable接口,实现.run()方法,创建Thread类对象,将Runnable的子类以参数形式传递到Thread类的构造方法中。 然后Thread类的对象.start()方法,启动线程。此种方式为:当多个线程执行中一资源。
区别:当一个类已经继承了一个类,但还需要执行多线程。这时,就不能继承Thread类了,因为java只支持单继承。
售票的例子:
用继承Thread类的方法做,会发现每创建一个线程,他们中的资源都是独立的。所以每个线程都有100张票。虽然可以用 private static int count=100;但不建议用静态,因为生命周期太长。
class Ticket extends Thread {
private int count = 100;
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
if (count > 0) {
System.out.println(Thread.currentThread().getName()
+"-----------" + count--);
}
}
}
}
public classThreadDemo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Tickett1 = newTicket();
Tickett2 = newTicket();
Tickett3 = newTicket();
Tickett4 = newTicket();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
IllegalThreadStateException:无效线程状态异常。
一个线程多次start( )开启,会报此异常。
实现Runnable方式
class Ticket implements Runnable {
private int count = 200;
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
if (count > 0) {
System.out.println(Thread.currentThread().getName()
+"-----------" + count--);
}else{
break;
}
}
}
}
public classThreadDemo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Tickett = newTicket();
Threadt1 = newThread(t);
Threadt2 = newThread(t);
Threadt3 = newThread(t);
Threadt4 = newThread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
可能会打印出0,-1,-2等数据的情况。原因分析
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完。另一个线程参与进来扫行,导致共享数据的错误。
解决办法:对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。
JAVA对于多线程的安全问题提供了专业的解决方式。
就是同步代码块:
synchronized(对象){
需要被同步的代码
}
对象 可以看做一个标志位,有两个值1和0, 当一个线程进入同步后,将对象改为0。其它线程则无法进入。专业术语就是锁。
同步的前提:
1, 必须要有两个或者两个以上的线程。
2, 必须多个线程使用同一个锁。
必须保证同步中只能有一个线程在运行。
好处:解决了多线程的安全问题。
弊端:多个线程需要判断锁,较为消耗资源。
同步函数:
在函数上加上synchronized修饰符即可
同步的表现形式:
1,同步代码块。
2,同步函数。
两者有什么不同:
同步代码块使用的锁是任意对象。
同步函数使用的锁是this。
注意:对于static的同步函数,使用的锁不是this。是 类名.class 是该类的字节码文件对象。 涉及到了单例设计模式的懒汉式。
同步的好处:解决了线程的安全问题。
弊端:
较为消耗资源。
同步嵌套后,容易死锁。
要记住:同步使用的前提:
1,必须是两个或者两个以上的线程。
2,必须是多个线程使用同一个锁。
这是才可以称为这些线程被同步了。
死锁:同步中嵌套同步,而锁却不同
wait(),notify(),notifyAll(),这些方法用于同步中。因为要对持有监视器(锁)的线程操作,所以要使用在同步中,因为只有同步还有锁。
notify()其实调用的就是wait(0)
为什么这些操作的方法要定义到Object类中?
因为这些方法在操作同步中线程 时,都必须要标识它们所操作线程持有的锁,只有同一个锁上的被等待线程,可以被同一个锁上的notify()唤醒。不可对不同锁的notify唤醒。也就是说,wait和notify必须 是一个锁。而锁可以是任意对象。任意对象的方法都定义在object类中。
将同步Synchronized替换成现实Lock操作。
将Object中的wait,notifynotifyAll,替换了Condition对象。
将同步Synchronized替换成现实Lock操作。
将Object中的wait,notifynotifyAll,替换了Condition对象。
该对象可以Lock锁 进行获取。
该示例中,实现了本方只唤醒对方操作。
Lock:替代了Synchronized
lock
unlock
newCondition()
Condition:替代了Object wait notify notifyAll
await();
signal();
signalAll();
停止线程
stop方法已经过时,不再使用
如果停止线程:只有一个方法,run方法结束
当开启多个线程运行,运行代码通常是循环结构,只要控制了循环,就可以让run方法结束
特殊情况
当线程处于冻结状态,就不会读取标记,那么线程就不会结束。
interrupt()强制清除冻结、等待状态,会执异常
当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除,
强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束
Thread提供interrupt()方法
setDaemon(booleanb): 守护线程
后台线程,依靠前台线程,前台线程都结束后,后台线程不管有没有执行完run方法都会结束
join():抢夺CPU的执行权
当A线程执行到B线程的Join()方法时,A就会等待,等B线程执行完,A再执行
setPriority(intnum)、getPriority():设置和返回线程优先级
- ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ----
- ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ----
- ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ----
- ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ----
- ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ----
- ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ----
- ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ----
- ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ----
- ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ----
- ----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
- <a href="http://www.pianopro.cn">通州钢琴培训</a>
- 尖峰在线培训 http://www.jianfengedu.com/
- 培训
- 培训
- 培训
- 培训
- 培训
- 培训
- mysql5.6分区记录
- poj3006——Dirichlet's Theorem on Arithmetic Progressions
- Dungeon Game
- BZOJ1024
- DF Engine Export 无法到处到数据库
- ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ----
- hdu oj 1849 Rabbit and Grass
- Codeforces #316 DIV2
- 当一个线程进入一个对象的synchronized() 方法后,其他线程是否可以进入此对象的其他方法
- Xcode6制作静态链接库和framework
- java动态代理的两种方式---jdk和cglib
- CodeForces 245C Game with Coins
- Android中定时器的3种实现方法
- 【二十三】Wireshark抓取安卓APP包