public class TestThread01 {
public static void main(String args[]) {
MyThread mt1 = new MyThread(); Thread t1 = new Thread(mt1);
Thread t2 = new Thread(mt1);
t1.start();
t2.start(); }}class MyThread implements Runnable {
int ticket = 20; public void run() {
synchronized (this) {
for (int i = 0; i < 25; i--) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + " "
+ ticket);
ticket--; }
}
}
}
}
public static void main(String args[]) {
MyThread mt1 = new MyThread(); Thread t1 = new Thread(mt1);
Thread t2 = new Thread(mt1);
t1.start();
t2.start(); }}class MyThread implements Runnable {
int ticket = 20; public void run() {
synchronized (this) {
for (int i = 0; i < 25; i--) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + " "
+ ticket);
ticket--; }
}
}
}
}
看看这个关键字
如果ticket写在system.out里面的话,下面就可以共享,为什么 ????
class TestThread01
{
public static void main(String args[])
{
MyThread mt1 = new MyThread();
Thread t1 = new Thread(mt1);
Thread t2 = new Thread(mt1);
t1.start();
t2.start();
}}class MyThread implements Runnable
{
int ticket = 20;
public void run(){
for( int i=0; i <25 ; i--)
{
if(ticket > 0)
{
System.out.println(Thread.currentThread().getName()+" "+ticket--);
}
}
}
Thread t1 = new Thread(mt1);
Thread t2 = new Thread(mt1);因为你只new 了一次Runnalbe接口,数据都是从这一个里面取,
你想要的结果应该是这样的,
static int ticket = 20;
MyThread mt1 = new MyThread();
Thread t1 = new Thread(mt1); MyThread mt2= new MyThread();
Thread t2 = new Thread(mt2);
class TestThread01
{
public static void main(String args[])
{
MyThread mt1 = new MyThread();
new Thread(mt1).start();
new Thread(mt1).start();
new Thread(mt1).start();
new Thread(mt1).start();
new Thread(mt1).start();
new Thread(mt1).start();
new Thread(mt1).start();
new Thread(mt1).start();
}}class MyThread implements Runnable
{
int ticket = 20;
public void run(){
for( int i=0; i <25 ; i--)
{
if(ticket > 0)
{
System.out.println(Thread.currentThread().getName()+" "+ticket--);
}
}
}
}
Thread-0 20
Thread-0 17
Thread-2 18
Thread-2 12
Thread-1 19
Thread-1 9
Thread-2 10
Thread-6 11
Thread-5 13
Thread-0 14
Thread-4 15
Thread-3 16
Thread-4 2
Thread-0 3
Thread-5 4
Thread-6 5
Thread-2 6
Thread-1 7
Thread-7 8
Thread-3 1
所以就存在读写的时候出现一些脏数据。
以下是我执行两次的结果//第一次
Thread-0 20
Thread-0 19
Thread-0 18
Thread-0 17
Thread-0 16
Thread-0 15
Thread-0 14
Thread-0 13
Thread-0 12
Thread-0 11
Thread-0 10
Thread-0 9
Thread-0 8
Thread-0 7
Thread-0 6
Thread-0 5
Thread-0 4
Thread-0 3
Thread-0 2
Thread-0 1
Thread-1 20//第二次
Thread-0 20
Thread-0 19
Thread-0 18
Thread-0 17
Thread-0 16
Thread-0 15
Thread-0 14
Thread-0 13
Thread-0 12
Thread-0 11
Thread-1 11
Thread-1 9
Thread-0 10
Thread-0 7
Thread-1 8
Thread-1 5
Thread-1 4
Thread-1 3
Thread-0 6
Thread-1 2
Thread-0 1//第三次
Thread-0 20
Thread-1 20
Thread-0 19
Thread-0 18
Thread-0 17
Thread-0 16
Thread-0 15
Thread-0 14
Thread-0 13
Thread-0 12
Thread-1 10
Thread-0 10
Thread-0 8
Thread-0 7
Thread-1 9
Thread-1 5
Thread-1 4
Thread-1 3
Thread-0 6
Thread-1 2
Thread-0 1从结果可以看出来,每次运行结果都会出现重复的几个数据,第一次是20重复,第二次是11重复,第三次是20和10重复。
重复n次执行数据就是20+n。
出现这种情况是因为两个线程都去读写一个数据,当线程1读写完线程2再去读写时不会出现重复。但是如果线程1执行完读还未执行写时执行权让给了线程2,那么线程2读到的就是同一个数。
以第一次结果为例:
程序启动时,两个线程同时读取到了20。
但是接下来线程运行权全部被线程1抢占,于是出现了线程1连续输出了接下来的数据。
最后线程2抢占了运行权进行了控制台输出了最开始他读到的20 。如果改成System.out.println(Thread.currentThread().getName()+" "+ticket--);。由于读写放在一条指令执行,就避免了输出重复数据。Thread-0 20
Thread-0 19
Thread-0 18
Thread-0 17
Thread-0 16
Thread-0 15
Thread-1 14
Thread-0 13
Thread-0 11
Thread-1 12
Thread-0 10
Thread-0 8
Thread-0 7
Thread-0 6
Thread-0 5
Thread-1 9
Thread-0 4
Thread-1 3
Thread-1 1
Thread-0 2
如果改成线程同步,那么就不存在两个线程同时去读写一个数据。Thread-0 20
Thread-0 19
Thread-0 18
Thread-0 17
Thread-0 16
Thread-0 15
Thread-0 14
Thread-0 13
Thread-0 12
Thread-0 11
Thread-0 10
Thread-0 9
Thread-0 8
Thread-0 7
Thread-0 6
Thread-0 5
Thread-0 4
Thread-0 3
Thread-0 2
Thread-0 1