---恢复内容开始---
在这个代码中,我们在main方法中,写了一个for循环,在Tred类中创建了一个线程,并重写了它的run方法,在run方法中写了一个for循环,当我们运行此程序时结果如下:
主程序中的for循环,输出了五次之后,线程Tred启动,也执行了五次,这是线程正常运行的情况,没有发生数据的混乱
当应用中存在多个线程时,程序的执行流程将不再保证会按照原有单线程的执行流程,有可能会出现各个线程之间互相打断的情况。下面我们来看看多线程安全问题,我们经常提到的卖票问题:
package com.itycl.ch01;
public class ThreadDemo2 {
public static void main(String[] args) {
TicketWindow tw1 = new TicketWindow();
TicketWindow tw2 = new TicketWindow();
TicketWindow tw3 = new TicketWindow();
tw1.start();
tw2.start();
tw3.start();
}
}
public static void main(String[] args) {
TicketWindow tw1 = new TicketWindow();
TicketWindow tw2 = new TicketWindow();
TicketWindow tw3 = new TicketWindow();
tw1.start();
tw2.start();
tw3.start();
}
}
class TicketWindow extends Thread{
private int ticket = 100;
public void run(){
while(true){
if(ticket > 0){
System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket-- +"张票");
}
}
}
}
private int ticket = 100;
public void run(){
while(true){
if(ticket > 0){
System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket-- +"张票");
}
}
}
}
运行结果:Thread-0正在出售第100张票
Thread-2正在出售第100张票
Thread-1正在出售第100张票
Thread-1正在出售第90张票
Thread-2正在出售第80张票
Thread-1正在出售第98张票
在此程序中我们创建个三个线程,把他们当作卖票的窗口,共同去卖100张票,当我们看到,运行结果,Thread-0,Thread-1,Thread-2,都同时在卖第100张票,此时就出现了错票,这是为什么呢?我们发现我们的三个线程都能去卖同一张票。这时我们在private int ticket = 100;加关键字static修饰变量时,将变量设置为共享数据,就能解决此问题了。
package com.itycl.ch01;
public class ThreadDemo2 {
public static void main(String[] args) {
TicketWindow tw1 = new TicketWindow();
TicketWindow tw2 = new TicketWindow();
TicketWindow tw3 = new TicketWindow();
tw1.start();
tw2.start();
tw3.start();
}
}
public static void main(String[] args) {
TicketWindow tw1 = new TicketWindow();
TicketWindow tw2 = new TicketWindow();
TicketWindow tw3 = new TicketWindow();
tw1.start();
tw2.start();
tw3.start();
}
}
class TicketWindow extends Thread{
private static int ticket = 100;
public void run(){
while(true){
if(ticket > 0){
private static int ticket = 100;
public void run(){
while(true){
if(ticket > 0){
System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket-- +"张票");
}
}
}
}
}
}
}
}
当多条语句在操作同一个线程共享数据时,
一个线程对多条语句只执行了一部分(,CPU就切换到其他线程去了),还没执行完,
另一个线程就参与进来执行,导致共享数据的错误。
这时候引出来了 synchronized关键字,在run方法中加入了同步代码块,它相当于一把锁,当它持有资源的时候,别的线程不能进入来执行,只有它 运行完了,其他的线程才能运行
package com.itycl.ch01;
public class ThreadDemo2 {
public static void main(String[] args) {
TicketWindow tw1 = new TicketWindow();
TicketWindow tw2 = new TicketWindow();
TicketWindow tw3 = new TicketWindow();
tw1.start();
tw2.start();
tw3.start();
}
}
public static void main(String[] args) {
TicketWindow tw1 = new TicketWindow();
TicketWindow tw2 = new TicketWindow();
TicketWindow tw3 = new TicketWindow();
tw1.start();
tw2.start();
tw3.start();
}
}
class TicketWindow extends Thread{
private int ticket = 100;
Object o=new Object();
public void run(){
while(true){
private int ticket = 100;
Object o=new Object();
public void run(){
while(true){
synchronized(o){
if(ticket > 0){
if(ticket > 0){
System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket-- +"张票");
}
}
}
}
}
}
}
}
}
---恢复内容结束---