java实现线程同步,如果有多个线程同时进行,那么程序很有可能会出错。
例如 模拟一个卖票程序
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//2.创建线程上执行的任务对象
MyTask m=new MyTask();
/*//3.创建线程
Thread t=new Thread(m);
//4.启动线程
t.start();*/
new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
}
}
//1. 创建一个任务类 ,实现Runnable
class MyTask implements Runnable
{
private int tickets=50;
public void run() {
// TODO Auto-generated method stub
while(true)
{
if(tickets>0)
{
System.out.println(Thread.currentThread().getName()+": "+tickets);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tickets--;
}
}
}
}
输出结果就有可能会有重复的票号
Thread-1: 50
Thread-2: 50
Thread-0: 50
Thread-3: 50
Thread-1: 49
Thread-2: 48
。。。
所以在编写类似的程序的时候必须要在当前线程加锁,
在此可以有两种方法,一种是加明锁,也就是java.util中的Lock;
另一种则是加暗锁,也就是在写run方法的时候加上synchronized;
synchronized能传递一个Object对象,这个对象类似于当前的一个资源,在开始的时候值为一,当开始执行的时候,值会变成零,所以在其他线程想要用此资源的时候,资源数为零,因此,只有当这个方法执行完毕,其他线程才能够执行。
加暗锁
public class Test { //用synchronized方法锁定当前线程
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//2.创建线程上执行的任务对象
MyTask m=new MyTask();
/*//3.创建线程
Thread t=new Thread(m);
//4.启动线程
t.start();*/
new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
}
}
//1. 创建一个任务类 ,实现Runnable
class MyTask implements Runnable
{
private int tickets=50;
private String s="";
public void run() {
// TODO Auto-generated method stub
while(true)
{
synchronized(s)
{
if(tickets>0)
{
System.out.println(Thread.currentThread().getName()+": "+tickets);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tickets--;
}
}
}
}
}
----------------------------------------------------------------------
加明锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//2.创建线程上执行的任务对象
MyTask m=new MyTask();
/*//3.创建线程
Thread t=new Thread(m);
//4.启动线程
t.start();*/
new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
}
}
//1. 创建一个任务类 ,实现Runnable
class MyTask implements Runnable
{
private int tickets=50;
private String s="";
Lock lock=new ReentrantLock();
public void run() {
// TODO Auto-generated method stub
while(true)
{
lock.lock(); //锁定下面的代码
if(tickets>0)
{
System.out.println(Thread.currentThread().getName()+": "+tickets);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tickets--;
}
lock.unlock(); //在这段代码执行后解锁
}
}
}
例如 模拟一个卖票程序
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//2.创建线程上执行的任务对象
MyTask m=new MyTask();
/*//3.创建线程
Thread t=new Thread(m);
//4.启动线程
t.start();*/
new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
}
}
//1. 创建一个任务类 ,实现Runnable
class MyTask implements Runnable
{
private int tickets=50;
public void run() {
// TODO Auto-generated method stub
while(true)
{
if(tickets>0)
{
System.out.println(Thread.currentThread().getName()+": "+tickets);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tickets--;
}
}
}
}
输出结果就有可能会有重复的票号
Thread-1: 50
Thread-2: 50
Thread-0: 50
Thread-3: 50
Thread-1: 49
Thread-2: 48
。。。
所以在编写类似的程序的时候必须要在当前线程加锁,
在此可以有两种方法,一种是加明锁,也就是java.util中的Lock;
另一种则是加暗锁,也就是在写run方法的时候加上synchronized;
synchronized能传递一个Object对象,这个对象类似于当前的一个资源,在开始的时候值为一,当开始执行的时候,值会变成零,所以在其他线程想要用此资源的时候,资源数为零,因此,只有当这个方法执行完毕,其他线程才能够执行。
加暗锁
public class Test { //用synchronized方法锁定当前线程
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//2.创建线程上执行的任务对象
MyTask m=new MyTask();
/*//3.创建线程
Thread t=new Thread(m);
//4.启动线程
t.start();*/
new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
}
}
//1. 创建一个任务类 ,实现Runnable
class MyTask implements Runnable
{
private int tickets=50;
private String s="";
public void run() {
// TODO Auto-generated method stub
while(true)
{
synchronized(s)
{
if(tickets>0)
{
System.out.println(Thread.currentThread().getName()+": "+tickets);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tickets--;
}
}
}
}
}
----------------------------------------------------------------------
加明锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//2.创建线程上执行的任务对象
MyTask m=new MyTask();
/*//3.创建线程
Thread t=new Thread(m);
//4.启动线程
t.start();*/
new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
}
}
//1. 创建一个任务类 ,实现Runnable
class MyTask implements Runnable
{
private int tickets=50;
private String s="";
Lock lock=new ReentrantLock();
public void run() {
// TODO Auto-generated method stub
while(true)
{
lock.lock(); //锁定下面的代码
if(tickets>0)
{
System.out.println(Thread.currentThread().getName()+": "+tickets);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tickets--;
}
lock.unlock(); //在这段代码执行后解锁
}
}
}